什么是反射?
平时使用 Java 类,通常是先知道类名,通过 new 关键字创建对象,再调用方法或属性。但如果运行时只知道类的名字符串呢?比如配置文件里动态指定的类名。这时候就需要用到反射了。
简单来说,反射机制允许在运行状态中,对任意一个类都能获取它的所有属性和方法;对任意一个对象,都能调用它的任意方法和属性。这种动态获取信息以及动态调用对象的方法的功能,就是 Java 语言的反射机制。
核心 API 概览
反射相关的类主要位于 java.lang.reflect 包中(除了 Class)。它们将类的类型、方法、属性都封装成了独立的类:
- Class:反射的基石,代表加载到内存中的类。
- Constructor:构造方法。
- Method:普通方法。
- Field:成员变量。
其中最重要的类是 Class,可以说反射的使用都是从获取 Class 实例开始的。
获取 Class 实例
要使用反射,必须先拿到 Class 对象的实例。常用的方式有三种:
- 对象.getClass():适用于已有对象的情况。任何对象都可以调用此方法获得对应的 Class 实例。
- 类名.class:适用于编译期已知类名的情况。例如
String.class直接返回 String 类的 Class 实例。 - Class.forName(String name):适用于动态场景,尤其当类名是变量时。这是框架开发中最常用的方式。
// 示例:通过类名字符串获取 Class 实例
String className = "java.util.ArrayList";
Class<?> clazz = Class.forName(className);
操作构造器 (Constructor)
Constructor 类封装了构造方法的信息。拿到 Constructor 实例后,不仅能查看构造方法的参数和名称,还能直接创建新的对象实例。
// 获取带参数的构造方法
Constructor<?> constructor = clazz.getConstructor(String.class);
// 创建实例
Object obj = constructor.newInstance("初始化参数");
注意权限问题,如果构造方法是私有的,可能需要特殊处理才能访问。
操作字段 (Field)
Field 类将类的属性进行封装,可以获取属性的基本信息、当前值,也可以修改属性值。这对于操作私有字段非常有用。
// 获取声明的字段(包括私有)
Field field = clazz.getDeclaredField("privateVar");
// 暴力反射,绕过访问控制检查
field.setAccessible();
field.set(obj, );
field.get(obj);


