繁体   English   中英

用反射设置私有静态最终字段

[英]Setting private static final field with reflection

基于使用Java反射更改私有静态最终字段 ,我尝试设置私有静态最终字段。

(我知道这非常骇人听闻,但是这个问题与代码质量无关;与Java反射有关。)

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

class Main {

  static class Foo {
    private static final int A = 1;

    int getA() {
      return A;
    }
  }

  public static void main(String[] args) throws Exception {
    Field modifiers = Field.class.getDeclaredField("modifiers");
    modifiers.setAccessible(true);

    Field field = Foo.class.getDeclaredField("A");
    field.setAccessible(true);
    modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, 2);

    System.out.println(new Foo().getA()); // should print 2
  }

}

此打印

1

我已经使用OpenJDK 6和7,以及Oracle 7进行了尝试。

我不知道Java反射能提供什么保证。 但是,如果失败了,我以为会有一个Exception (实际上所有反射方法都会抛出异常)。

这是怎么回事

Java内在编译时初始化为常量表达式的 final字段

根据Java语言规范,使用在编译时可以求值的表达式初始化的任何static final *字段都必须编译为“内联”字段值的字节码。 也就是说,在Main类内部将不存在任何动态链接,告诉它在运行时从InterfaceA获得A的值。

反编译字节码,您会发现getA()的主体只是将常量1推入并返回它。


* -JavaWorld引用表示static final Kumar指出,在常量变量的定义中, 语言规范不要求使用static 变量 我认为Kumar是正确的,而JavaWorld是错误的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM