2013-08-29 83 views
1

我知道,有一個小竅門使用反射和嘗試它的思想來改變Long使用反射

Field field = Long.class.getField("MIN_VALUE"); 
    field.setAccessible(true); 
    Field modifiersField = Field.class.getDeclaredField("modifiers"); 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
    field.set(null, 2); 
    System.out.println(Long.MIN_VALUE); 

一個static final字段的值,但上面的代碼甚至不拋出任何異常變化Long.MIN_VALUE它也不會更改Long.MIN_VALUE的值。爲什麼這樣?

+0

我之前已經注意到類似的行爲。看起來Java緩存了原始(和'String')最終值,所以通過反射改變它們通常是行不通的。 – SamYonnou

+0

(以前的評論附錄)您會發現,如果您通過反思而不是直接訪問該字段,它將保留更改後的值而不是舊值。 – SamYonnou

回答

2

常量原始值直接編譯到使用代碼中。在運行時,該字段不再被訪問。因此,以後更改它對使用的代碼沒有任何影響。

我發現最好的參考就是從部分13.4.9 of the JLS以下段落:

If a field is a constant variable (§4.12.4), then deleting the keyword final or 
changing its value will not break compatibility with pre-existing binaries by 
causing them not to run, but they will not see any new value for the usage of 
the field unless they are recompiled. This is true even if the usage itself is 
not a compile-time constant expression (§15.28). 
+0

是的,這是一個愚蠢的問題:)謝謝 –