Java可通过反射修改私有成员变量,需用getDeclaredField()获取字段、setAccessible(true)绕过访问检查,再用set()/get()读写;JDK9+模块化下需--add-opens,SecurityManager可能禁止此操作。

Java 中可以通过反射获取并修改私有成员变量,关键在于调用 setAccessible(true) 跳过访问控制检查。
获取私有 Field 对象
使用 Class.getDeclaredField(String name) 获取私有字段(注意不是 getField(),后者只返回 public 字段):
- 必须传入准确的字段名,大小写敏感
- 该方法抛出
NoSuchFieldException,需捕获或声明异常 - 获取到的
Field默认不可访问,需主动设为可访问
绕过访问控制(关键步骤)
调用 field.setAccessible(true) 后,即可读写该私有字段:
- 此操作仅影响当前
Field实例,不影响 JVM 其他安全策略 - JDK 9+ 在模块化环境下可能受限,若运行在强封装模块中,需添加
--add-opens参数 - 某些安全管理器(SecurityManager)可能禁止该操作,生产环境慎用
读取和修改私有字段值
通过 get(Object obj) 和 set(Object obj, Object value) 操作字段:
立即学习“Java免费学习笔记(深入)”;
-
get()返回Object,基本类型会自动装箱(如int→Integer) -
set()传入新值时,类型必须匹配,否则抛出IllegalArgumentException - 静态字段传入
null作为对象参数;实例字段必须传入具体对象实例
完整示例代码
假设有一个类:class Person {<br> private String name = "Alice";<br> private int age = 25;<br>}
反射修改:
Person p = new Person();<br>Field nameField = Person.class.getDeclaredField("name");<br>nameField.setAccessible(true);<br>nameField.set(p, "Bob"); // 修改为 "Bob"<br><br>Field ageField = Person.class.getDeclaredField("age");<br>ageField.setAccessible(true);<br>ageField.set(p, 30); // 修改为 30<br><br>System.out.println(nameField.get(p)); // 输出 "Bob"<br>System.out.println(ageField.get(p)); // 输出 30


















