Java反射可通过Field类读写私有字段,需用getDeclaredField获取字段并调用setAccessible(true)绕过访问限制;静态字段操作传null,实例字段需传有效对象。

Java 反射机制可以通过 Class 对象获取类的成员变量(字段),并读写其值,即使字段是私有的。关键在于使用 Field 类及其相关方法,配合 setAccessible(true) 突破访问限制。
获取字段对象:public、private 都能拿到
通过 Class 的以下方法可获取 Field 实例:
-
getField(String name):仅获取 public 的**本类及父类继承的**字段,找不到抛NoSuchFieldException -
getDeclaredField(String name):获取本类声明的任意访问权限字段(包括 private、protected、default),但不包含父类字段 -
getFields()和getDeclaredFields()分别返回所有 public 字段或本类全部字段的数组
修改访问权限:绕过 private / protected 限制
默认情况下,反射不能直接操作非 public 字段。需调用:
-
field.setAccessible(true):临时取消 Java 语言访问检查(注意:JDK 9+ 模块系统下可能受--illegal-access策略影响) - 该设置只对当前
Field对象生效,不影响其他字段或编译期检查
读写字段值:区分静态与实例字段
Field.get(Object obj) 和 Field.set(Object obj, Object value) 是核心操作方法:
立即学习“Java免费学习笔记(深入)”;
- 若字段是 静态的(static),
obj参数传null即可,例如:field.get(null) - 若字段是 实例字段,
obj必须是对应类的有效实例,否则抛NullPointerException - 类型不匹配时(如给
int字段设String),会抛IllegalArgumentException - 基本类型字段(如
int、boolean)在get()后自动装箱为包装类;set()支持自动拆箱
完整示例:读写私有字段
假设有类:
public class Person {
private String name = "Alice";
public int age = 30;
private static String country = "China";
}
反射操作如下:
Person p = new Person();
Class<?> clazz = Person.class;
// 获取私有实例字段 name
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
System.out.println(nameField.get(p)); // 输出: Alice
nameField.set(p, "Bob");
System.out.println(nameField.get(p)); // 输出: Bob
// 获取静态私有字段 country
Field countryField = clazz.getDeclaredField("country");
countryField.setAccessible(true);
System.out.println(countryField.get(null)); // 输出: China
countryField.set(null, "USA");
System.out.println(countryField.get(null)); // 输出: USA


















