【Java】反射

反射相关类

类名 用途
Class 代表类的类型
Field 代表类的字段
Method 代表类的方法
Constructor 代表类的构造方法

Class 类

当 .java 文件被编译后,会生成对应的 .class 文件。开始运行后 JVM 会解读 .class 文件,解读完毕后 .class 文件会有一个对应的 java.lang.Class 类型的对象。我们可以通过反射获取到这种对象,来使用或修改属性与方法,可以在运行中改变一个类的信息,让其成为一个动态的类

相关方法

获取类的相关方法(返回 Class 类型)

方法签名 用途
getClassLoader() 获得类的加载器
getDeclaredClasses() 返回类中所有的类的对象和接口的对象(包括私有)
forName(String className) 根据类名返回类的对象
newInstance() 创建类的实例
getName() 获得类的完整路径

获取类中字段的相关方法(返回 Field 类型)

方法签名 用途
getField(String name) 获取公有属性字段

getFields()

获取所有公有属性字段
getDeclaredField(String name) 获取任一属性字段(包括私有)
getDeclaredFields() 获取所有属性字段(包括私有)

获取类中注解的相关方法(返回 Annotation 类型)

方法签名 用途
getAnnotation(Class annotationClass) 返回类中与参数类型匹配的公有注解对象
getAnnotation() 返回类中所有的公有注解对象
getDeclaredAnnotations(Class annotationClass) 返回类中任一与参数类型匹配的注解对象(包括私有)
getDeclaredAnnotations() 返回类中所有注解对象(包括私有)

获取类中构造器的相关方法(返回 Constructor 类型)

方法签名 用途
getConstructor(Class... parameterTypes) 获得类中与参数类型匹配的公有构造方法
getConstantors() 获得类中所有公共构造方法
getDeclaredConstructor(Class.. parameterTypes) 获得类中任一与参数类型匹配的构造方法(包括私有)
getDeclaredConstructors() 获得类中的所有构造方法(包括私有)

获得类中方法的相关方法(返回 Method 类型)

方法签名 用途
getMethod(String name, Class... parameterTypes) 获得类中与参数类型匹配的公有方法
getMethods() 获得类中所有公共方法
getDeclaredMethod(String name, Class.. parameterTypes) 获得类中任一与参数类型匹配的方法(包括私有)
getDeclaredMethods() 获得类中的所有方法(包括私有)

获取 Class 对象

Class.forName()

Class 类提供的静态方法 forName()

使用 Class.forName("类的全路径名") 获取到返回的对应类的类对象

Class studentClass = Class.forName("Student");

.class

每一个类都有的隐含的静态变量 class

使用 类名.class 获取到一个类对应的类对象

Class studentClass = Student.class;

.getClass()

每一个对象都有的方法 getClass() 继承于 Object 类

使用 实例.getClass() 获取到一个实例对应类的类对象

Student student = new Student();
Class studentClass = student.getClass();

反射示例

学生类

class Student {
    private String name;
    private int score;
    
    private Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    
    private void exam () {
        System.out.println(name + " 考了 " + score + " 分");
    }
    
    private void speak (String word) {
        System.out.println(name + " 说 " + word);
    }
}

反射获取类对象

Class studentClass = Class.forName("Student");

注意:

凡是通过反射 Class 类得到的私有 Field、私有 Method、私有 Constructor 都需要使用 Field/Method/Constructor 对应实例中的 setAccessible() 方法来获取访问权限

Constructor 构造实例

通过使用反射获得的 Class 对象来获取构造方法,以得到的构造方法构造对应实例

// 获取 Student(java.lang.String, int) 构造方法
Constructor studentDeclaredConstructor = 
    studentClass.getDeclaredConstructor(String.class, int.class);

// 修改访问权限为允许
studentDeclaredConstructor.setAccessible(true);

// 使用 newInstance() 实例化对象
Student student = 
    (Student) studentDeclaredConstructor.newInstance("张三", 100);

// 测试
// 自动调用 Object 中的实例方法 toString() 获取对象对应的 hashCode
System.out.println(student);

Field 获取属性的值

// 获取到 name 字段
Field studentNameDeclaredField = 
    studentClass.getDeclaredField("name");

// 获取到 score 字段
Field studentScoreDeclaredField = 
    studentClass.getDeclaredField("score");

// 修改访问权限为允许
studentNameDeclaredField.setAccessible(true);
studentScoreDeclaredField.setAccessible(true);

// 测试
// 通过 Field 中的实例方法 get(instance) 获取对应实例中对应字段的值
System.out.println(studentNameDeclaredField.get(student));
System.out.println(studentScoreDeclaredField.get(student));

Method 调用方法

// 获取到 exam() 方法
Method studentExamDeclaredMethod = 
    studentClass.getDeclaredMethod("exam");

// 获取到 speak(java.lang.String) 方法
Method studentSpeakDeclaredMethod = 
    studentClass.getDeclaredMethod("speak", String.class);

// 将访问权限修改为允许
studentExamDeclaredMethod.setAccessible(true);
studentSpeakDeclaredMethod.setAccessible(true);

// 调用对应实例中的对应方法
studentExamDeclaredMethod.invoke(student);
studentSpeakDeclaredMethod.invoke(student, "反射我是真的爱");

运行结果

【Java】反射_第1张图片

你可能感兴趣的:(#,Java,java,jvm,spring)