简短结论:普通 Java 反射本身不能直接修改 final 字段的值(会被 JVM 限制或优化挡住),但通过“先去掉 final 修饰符再改”的黑魔法,在多数情况下可以改成功,不过不保证、也不安全。
下面分情况说清楚。
class A {
private final int x = 10;
}
Field f = A.class.getDeclaredField("x");
f.setAccessible(true);
f.set(a, 20); // 通常抛 IllegalAccessException 或无效
原因:
final 字段在 JVM 语义上是“不可变”final 字段时会被限制modifiersField modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(a, 20);
✅ 在很多 JDK 8 及以前版本有效
❌ 在新 JDK(9+)中可能失效或被警告
这是最关键的一点。
private final int x = 10;
private final String s = "abc";
System.out.println(a.x); // 可能还是 10
static final int C = 10;
private final List<String> list = new ArrayList<>();
list 指向另一个对象:可能成功list 内部内容:本来就可以InaccessibleObjectException
java.base 等模块禁止非法反射setAccessible(true) 可能直接失败| 问题 | 答案 |
|---|---|
| 反射能直接改 final 吗 | ❌ 不能 |
| 用黑魔法能改吗 | ⚠️ 有时能 |
| 改了一定生效吗 | ❌ 不一定 |
| 生产环境能用吗 | ❌ 绝对不建议 |
如果你愿意,我可以:
你更想看哪一种?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。