You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17中如何通过反射修改非静态final字段?

在Java 17中通过反射修改非静态final字段的方法

你之前的代码在Java 17中报错,是因为从Java 12开始,Field类内部的modifiers字段被移除了,直接通过反射获取该字段会抛出NoSuchFieldException。针对非静态final字段,其实不需要修改modifiers,直接调用Field.set()方法就能完成修改,前提是绕过相关限制。

可行代码示例

import java.lang.reflect.Field;

class Foo {
    private final String bar;

    public Foo(String bar) {
        this.bar = bar;
    }

    public String getBar() {
        return this.bar;
    }
}

public class Example {
    public static void main(String[] args) throws Exception {
        Foo foo = new Foo("foobar");
        System.out.println("修改前: " + foo.getBar());

        Field field = Foo.class.getDeclaredField("bar");
        // 解除字段的访问限制
        field.setAccessible(true);
        
        // 直接修改字段值,无需操作modifiers
        field.set(foo, "new modified value");

        System.out.println("修改后: " + foo.getBar());
    }
}

关键注意事项

  • 仅适用于非静态final字段:静态final字段在JVM初始化后会被JIT编译器缓存,几乎无法通过反射修改,这一点和你了解的一致。
  • 模块系统限制:如果你的代码是模块化项目(使用module-info.java),需要确保目标包被开放给java.base模块,或者启动时添加参数:java --add-opens 你的模块名/你的包名=java.base Example,否则会抛出IllegalAccessException。
  • JIT优化问题:如果JIT已经将final字段的值内联到调用代码中,修改后可能看不到预期效果。可以通过添加-Xint参数禁用JIT编译,或者确保代码逻辑不会触发内联优化。
  • 生产环境谨慎使用:这种操作打破了Java的封装设计和不可变性约定,可能导致不可预期的bug,仅建议用于调试、测试等特殊场景。

内容的提问来源于stack exchange,提问作者godfather

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:55:24