JDK26的JEP 500属性

前言

JDK26的JEP 500属性,为未来"final 真正不可变"做准备,通过深度反射修改 final 字段将触发运行时警告

使用例子

csharp 复制代码
public class FinalFieldDemo {

    // 常量表达式初始化: javac 把读取折叠成 ldc "original", 反射改完普通读取仍是旧值
    private final String name = "original";

    // 非常量表达式初始化: 编译成 getfield, 反射改完普通读取能看到新值
    private final String tag = new String("original");

    public static void main(String[] args) throws Exception {
        FinalFieldDemo demo = new FinalFieldDemo();

        System.out.println("=== 修改前 ===");
        System.out.println("  直接读 name = " + demo.name);
        System.out.println("  直接读 tag  = " + demo.tag);

        // 深反射改 final: JDK 26 默认 warn 模式下写入成功, 仅在 stderr 打印一次 WARNING
        Field nameField = FinalFieldDemo.class.getDeclaredField("name");
        nameField.setAccessible(true);
        Field tagField = FinalFieldDemo.class.getDeclaredField("tag");
        tagField.setAccessible(true);

        System.out.println("=== 修改后 ===");
        System.out.println("  写 name = " + write(nameField, demo, "hacked-name"));
        System.out.println("  反射读 name = " + nameField.get(demo) + "   <- 反射读到的才是真实内存值");
        System.out.println("  直接读 name = " + demo.name + "   <- 编译期 ldc 折叠, 看不到运行时改写");
        System.out.println("  写 tag  = " + write(tagField, demo, "hacked-tag"));
        System.out.println("  反射读 tag  = " + tagField.get(demo));
        System.out.println("  直接读 tag  = " + demo.tag + "   <- 真实 getfield, 与反射读一致");
    }

    /**
     * 写入 final 字段, 返回写入结果描述。
     * warn 模式(默认): 写入成功 + stderr 打印 WARNING;
     * deny 模式(未来 JDK 默认): 抛 IllegalAccessException
     * "unnamed module @xxx is not allowed to mutate final fields"。
     */
    private static String write(Field field, Object target, Object value) {
        try {
            field.set(target, value);
            return "成功";
        } catch (IllegalAccessException e) {
            return "被拒绝 -> " + e.getMessage();
        }
    }
}

输出结果为

总计

修改final值会发出警告,但是还是能修改成功

相关推荐
budingxiaomoli37 分钟前
Spring统一功能处理
java·后端·spring
某鹏1 小时前
网关选型:Go、Java、Graal 谁都不能完胜
后端
用户0247836530972 小时前
从屎山到防线:14 行状态迁移表,给任务系统装上防瞎跳闸门
后端
CQU_JIAKE2 小时前
11.13[体系结构】指标,五级流水线,八级流水线,虚实地址思考
后端
Flynn Liang2 小时前
可观测性与成本治理:一次对话的 17 个观测点
java·langchain·可观测性·micrometer·langchain4j·token 成本·llm 监控
金銀銅鐵3 小时前
带您看懂字节码指令(三):同一行加法,为什么有四种指令
java·jvm
panbook4 小时前
从0到1实现一个分布式时序数据库(三):主从复制、故障检测与切换
后端
上线再说4 小时前
图片从 8.2MB 压到 296KB:我把小程序图片链路的账单拆了一遍
后端
dpharness4 小时前
我原以为 MCP 装完就能用,直到工具列表是空的
后端
dpharness4 小时前
153 个 MCP 服务,我把工具数一个个数了一遍
后端