簡體   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