java反射操作成员变量的核心是field对象,需用getdeclaredfield获取字段并setaccessible(true)解除访问限制,再通过get/set读写值,注意处理static、泛型、数组及异常。

Java 反射中动态获取和设置成员变量,核心是通过 Field 对象操作。关键在于正确获取字段、解除访问限制、处理类型匹配与异常。
获取 Field 对象并解除私有访问限制
用 Class.getDeclaredField("fieldName") 获取指定名称的字段(包括 private),再调用 setAccessible(true) 跳过 Java 访问控制检查:
- 若字段不存在,抛出
NoSuchFieldException -
getDeclaredField不查找父类字段;需向上遍历父类用getSuperclass()配合重试 - 对 public 字段也可用
getField,但仅限本类及父类中 public 的字段
用 Field.get() 和 set() 读写对象字段值
调用 field.get(obj) 获取对象 obj 中该字段的当前值;field.set(obj, value) 设置新值:
-
obj为null时,仅适用于 static 字段;否则抛NullPointerException - 传入的
value类型必须与字段声明类型兼容,否则抛IllegalArgumentException(如 int 字段不能设 String) - 基本类型字段(如
int)读取返回包装类(Integer),设置时可自动拆箱;也可用getInt()/setInt()等专用方法避免装箱
处理静态字段与泛型/数组字段
静态字段属于类本身,get() 和 set() 的第一个参数传 null 即可:
- 判断是否为静态:用
Modifier.isStatic(field.getModifiers()) - 泛型字段在运行时已擦除,
field.getGenericType()可获取带泛型信息的类型,但实际读写仍按原始类型处理 - 数组字段可用
Array.get()/Array.set()操作元素,或直接用field.get(obj)得到整个数组引用
常见陷阱与安全建议
反射绕过编译期检查,运行时错误多发,需主动防御:
- 始终 try-catch
IllegalAccessException、IllegalArgumentException、NoSuchFieldException - 避免在高频路径(如循环内)反复调用
getDeclaredField,应缓存Field实例 - Android 或某些安全策略下,
setAccessible(true)可能被禁用,需提前检测并降级处理 - 修改 final 字段需额外修改
modifiers字段(通过反射修改Field.modifiers),但 JDK 12+ 已限制该行为,不推荐依赖
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











