无法使用Java反射更改静态最终字段? [英] Cannot change static final field using java reflection?

查看:68
本文介绍了无法使用Java反射更改静态最终字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近偶然发现使用Java反射更改私有静态最终字段并测试多基因润滑剂的 EverythingIsTrue 类,可以正常工作, System.out.format("Everything is%s",false); 打印一切正确的确如此.但是当我将代码更改为

I recently stumbled upon Change private static final field using Java reflection and tested polygenelubricants' EverythingIsTrue class, works fine, System.out.format("Everything is %s", false); prints Everything is true indeed. But when I change the code as

public class EverythingIsTrue {

    public static final boolean FALSE = false;

    static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, newValue);
    }

    public static void main(String[] args) throws Exception {
        setFinalStatic(EverythingIsTrue.class.getField("FALSE"), true);
        System.out.format("Everything is %s", FALSE);
    }
}

它打印

Everything is false

有人知道为什么吗?setFinalStatic是否实际起作用?

Does anybody know why? Does setFinalStatic actually work or not?

推荐答案

在访问原始的静态final字段时,Java编译器将假定该值为常数,并内联该值,而不是生成访问该字段的代码.这意味着编译器将使用对 FALSE 字段的引用替换为值为 false 的引用.如果使用反射来访问该字段,您将看到该字段的值实际上已更改.

When accessing primitive static final fields, the Java compiler will assume that the value is a constant and inline the value instead of generating code that accesses the field. This means that the compiler will replace with the reference to the FALSE field with the value false. If you use reflection to access the field, you will see that the value of the field has actually changed.

这不适用于非原始字段,因为在编译时无法内联对象引用的值.

This will not work for non-primitive fields, as the value of an object reference can not be inlined at compile time.

这篇关于无法使用Java反射更改静态最终字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆