2012-09-09 41 views
7

我跑到下面的程序,Java的String問題

String firstString = "String"; 
    String secondString = "String"; 
    String thirdString = new String("String"); 
    System.out.println(firstString == secondString); 
    System.out.println(firstString == thirdString); 
    System.out.println(firstString.intern() == thirdString); 
    System.out.println(firstString.intern() == thirdString.intern()); 
    System.out.println(firstString.intern().equals(thirdString.intern())); 
    System.out.println(firstString == thirdString); 

和我的輸出是

true 
false 
false 
true 
true 
false 

我瞭解到,JVM池字符串內容相同的字符串相同。是對的嗎?如果那是真的那麼爲什麼不firstString == thirdString返回false? jvm是否只彙集字符串,只初始化爲:「」,而不是新操作符?

+0

另請嘗試:'firstString == thirdString.intern()',以查看字符串文字是否自動內部化。 –

回答

6

池化僅與字符串文字有關 - 所以firstStringsecondString實際上是相同的對象 - 其中thirdString中明確要求在堆上創建新對象。

我推薦閱讀關於string literals in the spec的部分。

它提供了關於字符串如何以及何時彙集的更多信息。

此外,請注意這些子彈在段的末尾:

  • 在同一封裝中同一類(§8)內文字字符串(§7)表示相同的字符串的引用對象(§4.3.1)。
  • 同一包中不同類中的文字字符串表示對同一個String對象的引用。
  • 不同包中不同類中的文字字符串同樣代表對同一個String對象的引用。
  • 通過常量表達式計算的字符串(§15.28)在編譯時計算,然後視爲文字。
  • 在運行時通過串聯計算的字符串是新創建的,因此是不同的。
+0

好的,我同意你的解釋。我已經用堆中的「String」創建了一個新對象作爲thirdObject。我已經實習了。那麼在游泳池裏會有兩個對象嗎?第一個和第二個字符串將引用對象A(引用),第三個引用另一個(B)。 – vvekselva

0

thirdString不是來自泳池。它不是一個字符串文字,你用new運算符動態創建它。

secondString另一方面 - 從池中取出(爲其指定一個字符串文字),因此同一對象被分配到firstStringsecondString

-1

「firstString == thirdString」返回false。

方法實習生「返回字符串對象的規範表示形式」。 如果分配的實習字符串:

thirdString=thirdString.intern(); 

最後的 「firstString == thirdString」 返回true

2

對於firstString和secondString,JVM將查找字符串池中,並返回 「字符串」 的參考。

對於thirdString,JVM不會查找字符串池,只會在堆中創建一個String對象。

對於OneString.intern(),JVM將查找字符串池中的引用,如果OneString不存在,則將OneString添加到字符串池並返回引用。

+0

我有一個查詢,添加池中的對象(字符串)是基於對象的哈希或對象內容(規範表示)。調用實體將添加到池中並返回標準表示,這意味着所有字符串都應該引用同一個字符串,因爲它們都具有相同的規範表示形式。 – vvekselva

+0

調用intern()後,字符串將被添加到字符串池中,並且String對象將引用字符串池中的新字符串引用。原來的字符串對象將在下次被GC收集。 –

+0

有沒有什麼辦法可以分析這個?我只想檢查實習生池的內容?有什麼辦法嗎? – vvekselva