[JAVA学习笔记] 反射机制
Java的反射通过Class类和java.lang.reflect类库实现。通过它们,可以动态获得类的构造器、方法、数据成员等信息,并创建新对象、执行方法和设置数据成员。
通过反射可以获得类的所有构造器、方法和数据成员,即便它们是被封装在类内部(private/protected/default)。因此,使用反射需要考虑,对违反访问权限的操作是否有风险(如日后更新导致封装改变)。
通过反射机制可以获取以下相关内容
- Class 对象
- 类名
- 修饰符
- 包信息
- 父类
- 实现的接口
- 构造器
- 方法
- 变量
- 注解
获取 Class 对象
Class.forName("org.test.Person"); //完整类名
String.class;
object.getClass();
Class 对象的几个方法
-
getFields() / getDeclaredFields()
getFields() 获得类的所有 public 数据成员,包括父类的;
getDeclaredFields() 获得类的所有数据成员 (public, protected, private, default),不包括父类。
其他 getXxx() / getDeclaredXxx() 逻辑与此类似。 -
newInstance()
创建实例,返回Object
类型。
通过 Class 对象获取实例
通过默认构造函数
Class c = ...;
Object obj = c.newInstance();
通过其他构造函数
Class c = ...;
Constructor constructor = c.getConstructor(String.class,int.class);
Object obj = c.newInstance("abc", 123);
由此可知,Class.newInstance()
方法可以获得类对象的实例,本质是执行了对应的构造函数,获取 Object 对象之后,就可以对其进行强制转换了。转换成接口后还可以调用接口中的函数。
强制类型转换
假定 Student 是 Person 的的子类
静态强制类型转换
Person person = new Student();
Student student = (Student)person;
动态强制类型转换
Person person = new Person();
Student student = Student.class.cast(person);
动态强制转换方法更灵活,但应用的场景并不多(Java SE5类库中仅有一例)
变量
通过如下方式访问一个类的成员变量:
Field[] fields = c.getFields();
返回的Field对象数组包含了指定类中声明为公有的(public)的所有变量集合。通过 Field 对象,可以访问变量名称,变量类型,或是设置或者获取变量的值。
要想获取私有变量,可以调用Class.getDeclaredField(name)
方法或者Class.getDeclaredFields()
方法, 但若要读取私有变量的值, 需要打开访问: field.setAccessible(true);
获得变量名字:
field.getName()
获得变量值:
field.get(this);
设置变量值:
Field[] fields = this.getClass().getDeclaredFields();
for(Field field : fields){
field.setAccessible(true);
field.set(this, 123);
}
这里要注意的是被 set 的对象的类型要和其第二个参数的类型一致(可以强制转换为相应类型即可,比如123可以转换为123.0,但是不能转换为"123")
方法
Method[] methods = aClass.getMethods();
此处不作整理。
网友评论