[JAVA学习笔记] 反射机制

[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();
此处不作整理。

你可能感兴趣的:([JAVA学习笔记] 反射机制)