反射【Reflect】
反射机制能获取正在程序运(Runtime)行的类的内部属性和方法
这种动态获取信息以及动态调用对象方法的功能叫做反射
反射的核心用途
使用反射是西安的框架工具:
Spring框架:依赖注入,Bean管理,AOP等
Hibernate/Mybatis:ORM映射,将数据库记录映射为java对象
Junit:通过反射查找带有@Test注解的方法
IDE:代码提示
核心类
java.lang.Class | 代表一个类或接口,反射的根源 |
java.lang.reflect.Constructor | 构造方法 |
java.lang.reflect.Field | 属性 |
java.lang.reflect.Method | 方法 |
java.lang.reflect.Array | 动态创建和数组的静态方法 |
java.lang.refelct.Modifier | 解析访问修饰符和金泰方法 |
获取Class对象的三种方法
public static void main(String[] args) throws ClassNotFoundException {//通过类.classClass clz1 = String.class;//通过对象.getClass()方法String s = new String();Class clz2 = s.getClass();//通过Class.forName("类的限定名")Class clz3 = Class.forName("java.lang.String");//ClassNotFoundExceptionSystem.out.println(clz1 == clz2);//trueSystem.out.println(clz2 == clz3);//true}
获取类的构造(Constructor)方法
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class<User> clz = User.class;//调用所有的构造方法Constructor<?>[] constructors = clz.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}//调用无参构造方法Constructor<User> constructor = clz.getConstructor();System.out.println(constructor);//通过无参constructor来获取User类User user = constructor.newInstance();user.setAge(19);user.setName("zhangsan");System.out.println(user);//通过有参constructor来获取User类Constructor<User> constructor2 = clz.getConstructor(String.class, int.class);User user1 = constructor2.newInstance("lisi",18);System.out.println(user1);}
获取属性
public static void main(String[] args) throws NoSuchFieldException {Class clz = String.class;//获取类中的公有属性Field[] fields = clz.getFields();System.out.println(Arrays.toString(fields));//获取本类的所有属性(包括私有属性)Field[] fields1 = clz.getDeclaredFields();System.out.println(Arrays.toString(fields1));//报错:这个方法因为获取的是String类型中的私有属性,对外是不可访问的,getFiled方法只能获取String或String父类中开放的属性//Field field = clz.getField("value");Field field = clz.getDeclaredField("value");System.out.println(field);}
获取方法
public static void main(String[] args) throws NoSuchMethodException {Class clz = String.class;//获取所有的公有方法Method[] methods = clz.getMethods();System.out.println(Arrays.toString(methods));//获取所有方法包括私有Method[] declaredMethod = clz.getDeclaredMethods();System.out.println(Arrays.toString(declaredMethod));//获取公有方法Method method = clz.getMethod("indexOf", int.class);System.out.println(method);//也可以获取私有方法Method method2 =clz.getDeclaredMethod("rangeCheck", char[].class, int.class, int.class);System.out.println(method2);}
拼接set,get方法获取本身的set,get方法
public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException, InvocationTargetException, IllegalAccessException {Class clz =Class.forName("com.xs.day16.demo.User");User user = new User();//获取所有属性Field[] fields = clz.getDeclaredFields();for (Field field : fields) {//获取该属性的名称String fieldName = field.getName();//拼接set,get方法String setMethodName = "set" +fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);String getMethodName = "get" +fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);//获取方法Method setMethod = clz.getMethod(setMethodName,field.getType());Method getMethod = clz.getMethod(getMethodName);if ("name".equals(fieldName)) {setMethod.invoke(user,"zhangsan");}if ("age".equals(fieldName)) {setMethod.invoke(user,18);}}System.out.println(user);}