2011-04-25 41 views

回答

14

它們具有相同的最終結果,但他們都沒有相同(它們會產生不同的字節碼; new String("foo").intern()版本實際上會經歷這些步驟,產生一個新的字符串對象,然後實施它)。從String#intern

兩個相關報價:

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

所有文字字符串和字符串值的常量表達式都被執行。

所以最終結果是一樣的:一個引用實參字符串「foo」的變量。

+0

在這種情況下,新的字符串(「foo」)。intern(),新創建的字符串對象不會添加到堆權? – foo 2011-04-25 10:18:32

+3

@foo:它可能是,但它可以立即用於GC的回收,因爲表達式的末尾沒有任何未完成的引用。我希望優化的JVM(如Sun/Oracle的HotSpot)在第一次傳遞時優化了'new String(「foo」)。intern()',一旦注意到調用構造函數沒有副作用。或者,它可能並不是因爲阻止這種緊密的循環,它不符合值得的門檻。 – 2011-04-25 10:23:51

+0

謝謝你。我想知道爲什麼有人會使用新的String(「foo」)成語來初始化字符串,如果我這樣做,我會創建兩個對象,一個在堆中,另一個在池中。除了使用統一模式初始化Java中的所有對象之外,是否還有使用新String(「foo」)的優勢? – foo 2011-04-25 10:29:51

4

public String intern()

由此可見,對於任何兩個串組S 和T s.intern() == t.intern()是 真當且僅當s.equals(t)true

所以我相信答案是肯定的,雖然第二種方法將不得不搜索整個池。

編輯

作爲sugegsted由T.J.克勞德

當調用實習生方法中,如果 池已經包含一個字符串 等於由equals(對象) 方法測定此字符串對象作爲 ,則返回從池中 字符串。否則,將此字符串 對象添加到池中,並且返回此String對象的引用 。

所有文字字符串和字符串值爲 的常量表達式被禁用。

+0

+1尋找到的文檔 – 2011-04-25 09:50:50

+0

我認爲比較符合的兩個引號是:*「當調用'intern'方法,如果該池已經包含一個等於這個'String'對象的字符串,並由'equals(Object)'方法確定,則返回該字符串,否則,這個String對象被添加到池中,並且引用返回這個String對象。「*和*」所有文字字符串和字符串值常量表達式都被禁用。「* – 2011-04-25 09:55:02

+0

現在,這應該是每個JVM的基礎嗎?所以如果我有一個集羣,它的行爲會有所不同。 – Pushkar 2011-04-25 10:30:31

0

是的,它們是相同的。基本上,intern()返回在整個虛擬機中唯一的字符串表示。這意味着您可以使用==而不是.equals()來比較字符串,從而節省性能。

3

第一個即

String foo = "foo"; 
在這一行

,我們創建使用字符串文本字符串。這意味着該字符串會自動保存在字符串常量池中。

在第二屆一個,即 -

String foo = new String("foo").intern(); 

這裏我們創建使用新的String(字符串)&然後手動將其保存到字符串常量池。如果我們沒有提及intern(),它將不會保存在String常量池中。

詳細說明,請參考此鏈接 -

http://javacodingtutorial.blogspot.com/2013/12/comparing-string-objects-intern-other.html

+1

這個答案不能錯誤。如果說第二個片段沒有調用'intern()'就沒有在池中的字符串顯然是錯誤的,因爲它___still___使用文字'「foo」'。在這種情況下,'intern'的效果是,對String構造函數的調用不再成立,而'foo'指向文本版本'「foo」'而不是新構建的。 – Tom 2018-01-07 17:31:45