Java反射机制的核心能力是在运行时动态获取类结构并操作私有成员,需三步:1. 通过Student.class、obj.getClass()或Class.forName()准确获取Class对象;2. 用getDeclaredField/Method定位本类私有成员;3. 调用setAccessible(true)解除访问限制后读写或调用。

Java 反射机制的核心能力,就是在运行时“看清”一个类的完整结构,并绕过访问控制去读写私有成员——关键不在于能不能做,而在于三步必须做对:拿到 Class 对象、定位目标成员、解除访问限制。
第一步:稳准获取 Class 对象
这是所有反射操作的起点,三种方式适用不同场景,不能混用错时机:
-
已知类名且编译期可见:直接用
Student.class,最轻量、无异常、性能最好 -
已有对象实例:调用
obj.getClass(),适合工具方法接收泛型对象后反推类型 -
类名来自配置或用户输入:必须用
Class.forName("com.example.Student"),会触发类加载,需捕获ClassNotFoundException
注意:这三种方式返回的是同一个 Class 实例(JVM 中每个类仅有一个 Class 对象),可安全用于后续所有操作。
第二步:精准定位私有字段或方法
Class 提供两类 API,区别在于是否包含继承成员:
立即学习“Java免费学习笔记(深入)”;
-
getDeclaredField("age")或getDeclaredMethod("eat", String.class)—— 只查本类声明的成员,这是操作私有成员的唯一正确入口 -
getField("name")或getMethod("study")—— 只返回 public 成员(含父类 public),对 private 完全不可见
若字段/方法不存在,会抛出 NoSuchFieldException 或 NoSuchMethodException,建议提前用 getDeclaredFields() 或 getDeclaredMethods() 扫描验证。
第三步:突破封装,安全读写与调用
获取到 Field 或 Method 后,必须显式调用 setAccessible(true),否则运行时仍会抛出 IllegalAccessException:
-
读取私有字段:先
field.setAccessible(true),再field.get(obj) -
修改私有字段:先
field.setAccessible(true),再field.set(obj, newValue) -
调用私有方法:先
method.setAccessible(true),再method.invoke(obj, "apple")
这个步骤不可省略,也不建议全局设置 SecurityManager 来禁用——它不是“黑科技”,而是 JVM 明确设计的受控突破机制。
实战小提醒
反射操作本身不复杂,但容易忽略两个细节:
- 修改 final 字段需额外调用
field.set(null, newValue)(静态 final)或先用反射修改其修饰符字段,实际业务中极少需要 - JDK 9+ 起,模块系统默认限制对非开放包的反射访问,如遇
InaccessibleObjectException,需在启动参数加--add-opens java.base/java.lang=ALL-UNNAMED


















