Java反射修改字段值核心是Field.set(),需调用setAccessible(true)绕过访问限制,基本类型自动装箱,静态字段传null,注意处理IllegalAccessException、IllegalArgumentException和NullPointerException异常。

Java中通过反射修改对象字段值,核心就是用 Field.set() 方法。但要注意访问权限、基本类型包装、静态字段等细节,否则容易抛异常。
确保字段可访问(绕过private限制)
默认情况下,private字段无法直接访问,必须调用 setAccessible(true) 打开权限:
Field field = obj.getClass().getDeclaredField("fieldName");
field.setAccessible(true); // 关键一步,否则会抛 IllegalAccessException
field.set(obj, newValue);
- 对 public 字段也可调用,无副作用
- Java 9+ 在某些安全策略下可能受限(如模块系统启用时),需额外配置
处理基本类型字段(自动装箱/拆箱)
Field.set() 只接受 Object 类型参数,所以给 int/boolean 等基本类型赋值时,必须传对应包装类实例:
-
field.set(obj, 42);→ 自动装箱为Integer,适用于int字段 -
field.set(obj, true);→ 自动装箱为Boolean,适用于boolean字段 - 不能传
null给基本类型字段,否则抛IllegalArgumentException
修改静态字段要传 null 作为实例参数
静态字段属于类而非实例,调用 set() 时第一个参数必须为 null:
立即学习“Java免费学习笔记(深入)”;
Field staticField = clazz.getDeclaredField("STATIC_VALUE");
staticField.setAccessible(true);
staticField.set(null, "new static value"); // 实例参数为 null
- 若误传对象实例,不会报错但实际未生效(JVM忽略该参数)
- 建议配合
Modifier.isStatic(field.getModifiers())判断后统一处理
注意常见异常和规避方式
实际使用中容易遇到三类异常:
-
IllegalAccessException:没调setAccessible(true)或安全管理器禁止 -
IllegalArgumentException:类型不匹配(如给 String 字段传 Integer)、或给基本类型传 null -
NullPointerException:目标对象为 null(非静态字段场景)
稳妥做法是加 try-catch,并在设值前用 field.getType().isAssignableFrom(value.getClass()) 做简单类型校验(注意基本类型需特殊处理)。


















