目录
反射
获取Class类对象 (字节码文件对象)
我们要想通过反射去使用一个类,首先要获取到该类的字节码文件对象,也就是类型为Class类型的对象,获取方法有三种。
- 根据类的Class属性获取对应的Class对象。
- 调用对象的getClass()方法,返回该方法所属类的Class对象。
- 使用Class类中的静态方法forName(String ClassName)获取Class对象。该方法需传入字符串参数,参数的值是类的全路径。
方式一最方便。
方式三灵活性最高,可以把字符串的数据配置到配置文件中,就可以随时更改配置文件中的内容。
!: 一个类在内存中只有一个字节码文件对象。
反射获取构造方法对象
- Constructor<?>[] getConstructors(),返回所有公共构造方法对象的数组
- Constructor<?>[] getDeclaredConstructors(),返回所有构造方法对象的数组
- Constructor<?> getConstructor(),返回单个公共构造方法对象
- Constructor<?> getDeclaredConstructor(),返回单个构造方法对象
Constructor类中用于创建对象的方法
T newInstance() 根据指定的构造方法创建对象
举例
反射就是: 通过构造方法对象里面的方法来创建对象。
暴力反射 setAccessible(true)
虽然私有构造方法对象可以被获取到,但不能使用。
IllegalAccessException: Class com.YuZai.ClassLoaderTest.Test.test004 can not access a member of class com.YuZai.ClassLoaderTest.Pojo.Student with modifiers "private"
此时,可以使用 public void setAccessible(boolean flag): 值为true,取消访问检查.
来进行暴力反射。
反射获取成员变量对象
- Field[] getFields(),返回所有公共成员变量对象的数组。
- Field[] getDeclaredFields(),返回所有成员变量对象的数组。
- Field getField(String name),返回单个公共成员变量对象。
- Field getDeclaredField(String name),返回单个成员变量对象。
Field类中用于给成员变量赋值的方法 public void set(Object obj, Object value) 给Obj对象的成员变量赋值为value
举例
反射获取成员方法对象
- Method[] getMethods(),返回所有公共成员方法对象的数组,包括继承过来的方法。
- Method[] getDeclaredMethods(),返回所有成员方法对象的数组,不包括继承过来的方法。
- Method getMethod(String name, Class<?>… parameterTypes),返回单个公共成员方法对象。
- Method getDeclaredMethod(String name, Class<?>… parameterTypes),返回单个成员方法对象。
Method类中用于调用成员方法的方法 Object invoke(Object obj, Object… args)
Object invoke(Object obj, Object... args)
举例
通过反射越过泛型检查
通过反射可以做到平常不能做到的一些操作,比如访问类的私有成员方法、私有成员变量。
练习: 现有一个ArrayList集合,现在想在这个集合中添加一个字符串数据,如何实现?
解:通过反射越过泛型检查,获取到原始的方法及所调用的参数类型。
配置文件指定类类型
体现反射的灵活性。
相关面试题
反射主要还是要围绕着它的动态性来回答。
关于反射的理解?
Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
对Class类的理解?
答: Class实例对应着加载到内存中的一个运行时类。
框架 = 反射 + 注解 + 设计模式。