- 靜態字段屬於/同夥類類型
- 它由該類
- 的所有對象使用。如果類被加載通過在同一個JVM中使用兩個不同的類加載器,我們可以擁有兩個副本。
是否有任何方式/場景,我可以有兩個不同的值我的靜態副本?
是否有任何方式/場景,我可以有兩個不同的值我的靜態副本?
是的,你可以有這種情況下static final
基元。
讓我們看看下面的情況:
public static final int SOME_CONSTANT = 1
A.SOME_CONSTANT
public static final int SOME_CONSTANT = 2
如果您現在要啓動JVM(在類路徑中使用A和B),則A類中的靜態值爲1,而B類中的值爲2.這是因爲javac
編譯了每個.class文件的值。 B類擁有它自己的靜態副本,並且不引用A類。爲了解決這個問題,每當B類中的常量發生變化(即做一個乾淨的構建而不是增量構建)時,你必須重新編譯A類。請注意,這個問題只適用於static final
基元(int,long等)。
嗯非常感謝您瞭解這個問題的見解。但是這種情況會不會發生,即一個A類已經加載並且Blass B以同樣的方式卸載並重新加載和通信? 另外它非常類似於使用2類加載器加載類2和加載類。 所以我明白,在正常情況下,兩個線程不能擁有同一個STATIC字段的兩個不同值。 – sandejai
請注意,這不是運行時問題。這是編譯時問題。它與類加載器無關,是由包含不同值的已編譯的.class文件引起的。 –
如果你的C類是由兩個不同的類加載器CL1和CL2,
加載 後來有兩個實例C1值,java.lang.Class
C2描述你
類。然後在他們中的每一個(C1,C2)你在您的靜態字段f(f在C中定義)中可以有不同的值
。對於JVM而言,有些人甚至認爲技術上這兩個c1,c2
是不同的類。
是的,如果你有兩個類加載器,按照第3點。 –
另外,當將多線程的值更改變量變量對另一個線程立即不可見時。所以靜態字段可以同時有兩個值(在不同的核心緩存中) –
這不是兩個副本。考慮兩個B和D類的情況,他們都有一個靜態字段foo。我們會說我們有兩份foo嗎?當然不是,同樣的情況是,當我們有兩個加載器加載的「相同」類時:這兩個類被視爲與B和D不同。 – Ingo