2014-02-10 57 views
0

我明白我們有朝一日能有一個靜電場的兩個副本在JAVA

  1. 靜態字段屬於/同夥類類型
  2. 它由該類
  3. 的所有對象使用。如果類被加載通過在同一個JVM中使用兩個不同的類加載器,我們可以擁有兩個副本。

是否有任何方式/場景,我可以有兩個不同的值我的靜態副本?

+3

是的,如果你有兩個類加載器,按照第3點。 –

+0

另外,當將多線程的值更改變量變量對另一個線程立即不可見時。所以靜態字段可以同時有兩個值(在不同的核心緩存中) –

+0

這不是兩個副本。考慮兩個B和D類的情況,他們都有一個靜態字段foo。我們會說我們有兩份foo嗎?當然不是,同樣的情況是,當我們有兩個加載器加載的「相同」類時:這兩個類被視爲與B和D不同。 – Ingo

回答

0

是的,你可以有這種情況下static final基元。

讓我們看看下面的情況:

  1. A類具有public static final int SOME_CONSTANT = 1
  2. B類引用A.SOME_CONSTANT
  3. A類和B編譯
  4. B級變化public static final int SOME_CONSTANT = 2
  5. B類是無需重新編譯A類

如果您現在要啓動JVM(在類路徑中使用A和B),則A類中的靜態值爲1,而B類中的值爲2.這是因爲javac編譯了每個.class文件的值。 B類擁有它自己的靜態副本,並且不引用A類。爲了解決這個問題,每當B類中的常量發生變化(即做一個乾淨的構建而不是增量構建)時,你必須重新編譯A類。請注意,這個問題只適用於static final基元(int,long等)。

+0

嗯非常感謝您瞭解這個問題的見解。但是這種情況會不會發生,即一個A類已經加載並且Blass B以同樣的方式卸載並重新加載和通信? 另外它非常類似於使用2類加載器加載類2和加載類。 所以我明白,在正常情況下,兩個線程不能擁有同一個STATIC字段的兩個不同值。 – sandejai

+0

請注意,這不是運行時問題。這是編譯時問題。它與類加載器無關,是由包含不同值的已編譯的.class文件引起的。 –

0

如果你的C類是由兩個不同的類加載器CL1和CL2,
加載 後來有兩個實例C1值,java.lang.Class C2描述你
類。然後在他們中的每一個(C1,C2)你在您的靜態字段f(f在C中定義)中可以有不同的值
。對於JVM而言,有些人甚至認爲技術上這兩個c1,c2
是不同的類。

+0

事實確實如此,JVM將這兩個C類視爲兩個完全不相關的類。出於這個原因,情況與兩個班級相同,比如說B和D,他們碰巧有一個靜態字段'foo'。 – Ingo

+0

是的,我知道。實際上c1和c2可能是C類(我的意思是源文件的編譯版本)在不同的時刻。所以這兩個類是不同的,因爲字節碼可能完全不同。 –

+0

非常感謝peter.petrov,Ingo,Richard Tingle。 – sandejai

相關問題