反射

77 阅读1分钟

什么是反射?

  • Java的一种特性
  • 能够在程序运行过程中检查,获取,修改一个类的信息
    • 属性
    • 方法
    • 构造器

获取Class对象的三种方式

1. Class.forName

// 1. Class.forName()
Class<?> studentClass = Class.forName("Student");

2.类的class属性

// 2. 类的class属性
Class<Student> studentClass = Student.class;

3. 对象的 getClass() 方法

// 3. 对象的 getClass()方法
Student student = new Student();
Class studentClass = student.getClass();

通过反射创建类对象

1. 通过Class对象的newInstance()方法

Student student = (Student)studentClass.newInstance();

2. 通过 Constructoer对象的newInstance()方法

Constructor constructor = studentClass.getConstructor();
Student student = new Student();

构造器

获取所有构造器

Constructor[] declaredConstructors = studentClass.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor);
}
//结果
//public Student()
//public Student(java.lang.String,int)

属性

获取所有属性

Field[] fields = studentClass.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field.getName());
}
//结果;
//name
//age

方法

获得所有方法

Method[] declaredMethods = studentClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println(declaredMethod);
}
//结果
//private void Student.birthday()
//public void Student.study()

获取public方法并调用

//反射获取有参构造器
Constructor constructor = studentClass.getConstructor(String.class, int.class);
Student student = (Student) constructor.newInstance("Tom", 18);
Method studyMethod = studentClass.getMethod("study");
studyMethod.invoke(student);  // 输出 "Tom is studying

获取private方法并调用

私有方法必须设置.setAccessible(true)

// 获取并调用 birthday 方法
Method birthdayMethod = studentClass.getDeclaredMethod("birthday");
birthdayMethod.setAccessible(true);  // 必须设置为可访问
birthdayMethod.invoke(student);  // 输出 "Tom is now 19 years old."

反射的用途

  1. 可扩展性 -> 应用程序可以在运行时动态的引用或使用类
  2. 用于框架开发 -> 这些框架通常需要在运行时动态地创建对象、调用方法等
  3. 避免冗余

反射的缺点

  1. 性能开销大
  2. 破坏类的封装性
  3. 代码复杂,难以维护
  4. 类型不安全