Skip to content

反射机制

通过反射机制,可以更深入地控制程序运行过程。例如,可以在运行时检查类、获取类的属性和方法、调用方法、创建对象,还可以逆向控制程序的执行过程。

另外,Java 还提供了 Annotation(注解)功能,可以在类、方法、字段等元素上添加元数据,用于描述程序的结构和行为。

Class 类与 Java 反射

Java 反射(Reflection)是指在运行时动态获取类的信息,并操作类的属性、方法和构造方法。反射的核心类是 Class,它提供了大量 API 用于操作类的结构。

25021714.png

表 通过反射可以访问的 Class 对象的主要描述信息

在通过 getFields()getMethods() 方法依次获得权限为 public 的成员变量和方法时,将包含从父类中继承到的成员变量和方法;而通过 getDeclaredFields()getDeclaredMethods() 方法获得的是当前类中声明的成员变量和方法。

下面提供了三种获取 Class 对象的方式:

  • 方式 1:通过对象的 getClass() 方法
java
Person person = new Person();
Class<?> clazz1 = person.getClass();
  • 方式 2:通过类的 .class 语法
java
Class<?> clazz2 = Person.class;
  • 方式 3:通过 Class.forName()
java
Class<?> clazz3 = Class.forName("com.example.Person");

访问构造方法

Java 反射允许在运行时获取和调用构造方法,包括私有构造方法。

通过下列一组方法访问构造方法时,将返回 Constructor 类型的对象或数组,每个 Constructor 对象代表一个构造方法,利用 Constructor 对象可以操作相应的构造方法。

  • getConstructors():获取所有公共构造方法。
  • getConstructors(Class<?>... parameterTypes):获取特定参数类型的公共构造方法。
  • getDeclaredConstructors():获取所有构造方法(包括私有)。
  • getDeclaredConstructor(Class<?>... parameterTypes):获取特定参数类型的构造方法。

25021715.png

表 Constructor 类的常用方法

通过 java.lang.reflect.Modifier 类可以解析出 getModifiers() 方法返回值所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,如 Modifier.isPublic()Modifier.isPrivate()Modifier.isProtected()Modifier.isStatic() 等。

25021716.png

表 Modifier 类的常用的解析方法

例如,判断构造方法是否为私有:

java
Constructor<?> constructor = clazz.getDeclaredConstructor();
int modifiers = constructor.getModifiers();
if (Modifier.isPrivate(modifiers)) {
    System.out.println("私有构造方法");
}

获取构造方法:

java
import java.lang.reflect.Constructor;

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Person.class;

        // 获取所有构造方法(包括私有)
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }

        // 获取特定参数类型的构造方法
        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor);
    }
}

调用构造方法:

java
// 调用公共构造方法
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Person person = (Person) constructor.newInstance("Alice", 25);
System.out.println(person);

// 调用私有构造方法
Constructor<?> privateConstructor = clazz.getDeclaredConstructor();
privateConstructor.setAccessible(true);
Person privatePerson = (Person) privateConstructor.newInstance();
System.out.println(privatePerson);

访问成员变量

反射允许访问类的字段(包括 private 修饰的字段)。

通过下面一组方法访问成员变量时,将返回 Field 类型的对象或数组,每个 Field 对象代表一个类的成员变量,利用 Field 对象可以操作相应的成员变量。

  • getFields():获取所有公共成员变量。
  • getField(String name):获取特定名称的公共成员变量。
  • getDeclaredFields():获取所有成员变量(包括私有)。
  • getDeclaredField(String name):获取特定名称的成员变量。

25021801.png

表 Field 类的常用方法

获取成员变量:

java
import java.lang.reflect.Field;

Class<?> clazz = Person.class;

// 获取所有字段(包括私有字段)
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field);
}

// 获取特定字段
Field nameField = clazz.getDeclaredField("name");
System.out.println(nameField);

修改成员变量:

java
Person person = new Person("Bob", 30);

// 访问并修改私有字段
Field ageField = clazz.getDeclaredField("age");
ageField.setAccessible(true); // 解除访问限制
ageField.set(person, 35);

System.out.println(person);

访问方法

反射可以获取方法信息,并在运行时调用方法。

通过下列一组方法访问方法时,将返回 Method 类型的对象或数组,每个 Method 对象代表一个类的方法,利用 Method 对象可以操作相应的方法。

  • getMethods():获取所有公共方法。
  • getMethod(String name, Class<?>... parameterTypes):获取特定名称和参数类型的公共方法。
  • getDeclaredMethods():获取所有方法(包括私有)。
  • getDeclaredMethod(String name, Class<?>... parameterTypes):获取特定名称和参数类型的方法。

在反射中执行具有可变数量参数的构造方法时,需要将入口参数定义成二维数组。

25021802.png

表 Method 类的常用方法

获取方法:

java
import java.lang.reflect.Method;

Class<?> clazz = Person.class;

// 获取所有方法(包括私有方法)
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
    System.out.println(method);
}

// 获取特定方法
Method method = clazz.getDeclaredMethod("sayHello");
System.out.println(method);

调用方法:

java
Person person = new Person("Charlie", 28);

// 调用公共方法
Method method = clazz.getMethod("sayHello");
method.invoke(person);

// 调用私有方法
Method privateMethod = clazz.getDeclaredMethod("secretMethod");
privateMethod.setAccessible(true);
privateMethod.invoke(person);
编程洪同学服务平台是一个广泛收集编程相关内容和资源,旨在满足编程爱好者和专业开发人员的需求的网站。无论您是初学者还是经验丰富的开发者,都可以在这里找到有用的信息和资料,我们将助您提升编程技能和知识。
专业开发
高端定制
售后无忧
站内资源均为本站制作或收集于互联网等平台,如有侵权,请第一时间联系本站,敬请谅解!本站资源仅限于学习与参考,严禁用于各种非法活动,否则后果自行负责,本站概不承担!