2012-05-20 73 views
1
class A { 
    String s = "abc"; 
} 

class B { 
    String s = "abc"; 

    static public void main(String[]args) { 
      A a = new A(); 
      B b = new B(); 
      System.out.println("a.s==b.s : " + (a.s==b.s)); 
    } 
} 

輸出:Java:2個類中的2個文字(相同的內容)如何使用相同的實際字符串?

a.s==b.s : true 

如果文字寫入類文件的「常量池」的一部分,如何2班來2個文本(相同內容)使用相同字符串實習?編譯器如何將它們鏈接在一起?

+3

他們在課程加載時獲得實習。 –

回答

1

有一個字符串池其中所有實例String對象去。這實際上是一個HashMap<String>。請注意,String.intern()方法返回String;實施基本

if (stringPool.contains(this)) 
    return stringPool.get(this); 
else { 
    stringPool.put(this, this); 
    return this; 
} 

當在加載類String對象創建,它是通過調用intern(),其中有像共享所有類中的實例結果的結果所取代。

+0

Thanks.So你的意思是當加載'B類'時,一個新的String對象被創建,但隨後它可用於GC,因爲它被加載'class A'時創建的實際字符串替代? –

+1

那麼,我小心地說「有效」和「基本上」。當然沒有必要這樣做,而巧妙的實現可以避免它。 –

4

這也正是作爲Java Language Specification section 3.10.5說:

而且,文字始終是一個字符串是指String類的同一個實例。這是因爲字符串文字 - 或者更一般地說是常量表達式(§15.28)值的字符串 - 被「實施」,以便使用方法String.intern共享唯一實例。

有然後一個例子,對於其中的解釋包括:在不同的包不同的類內

文字字符串同樣表示爲相同字符串對象的引用。

String.intern()是記錄這樣的:

返回字符串對象的規範表示。

最初爲空的字符串池由類String私人維護。

當調用intern方法時,如果池已經包含與equals(Object)方法確定的String對象相等的字符串,則返回池中的字符串。否則,將此String對象添加到池中,並返回對此String對象的引用。

因此,對於任何兩個字符串s和t,當且僅當s.equals(t)爲真時,s.intern()== t.intern()才爲真。

所有文字字符串和字符串值的常量表達式都被執行。字符串文字在Java™語言規範的第3.10.5節中定義。

所有這些都指向您在示例中看到的行爲。

1

想象一下String.class中的一個static final Set<String>,其中包含所有實際的字符串。所有共享相同加載String類的類都將看到相同的實際字符串。由於String由一個根類加載器加載,因此它由單個JVM實例中的所有內容共享。

相關問題