2011-12-17 47 views
0

是這樣做的:String.intern是否只是複製Java中的對象引用?

String a = new String(); 
String b = a; 

,做:

String a = new String(); 
String b = a.intern(); 

是一樣的嗎?

實際上,基準都是一樣的,如果我測試:

String a = new String("te"); 
String b = a.intern(); 
String c = a; 
String d = "t" + "e"; 
System.out.print(a.equals(b)); 
System.out.print(b.equals(c)); 
System.out.print(a.equals(d)); 

原因字符串將永遠不會在字符串池?

回答

5

equals測試不檢查引用 - 他們檢查字符串平等。您應該使用==檢查參考身份。實際上,你正在讓普通新手Java錯誤反向 - 通常人們在使用==時應該使用equals。在這種情況下,所有這些將打印false,因爲有兩個String對象(常量池中的字符串和第一行中創建的新字符串)。如果我們分別把這些#1和#2,我們最終得到:

a = #2 // Explicit call to string constructor 
b = #1 // intern will return reference to constant pool instance 
c = #2 // Direct assignment 
d = #1 // Equivalent string constant, so reference to constant pool instance 

然而,你可能會發現這個有趣的:

String a = "te"; 
String b = a.intern(); 
String c = "t" + "e"; 
System.out.println(a == b); // true 
System.out.println(a == c); // true 

"te""t" + "e"是相等的字符串常量表達式,因此落得作爲單個字符串的引用,並且對文字池中已存在的字符串調用intern不會產生任何影響。

+0

但 字符串A = 「TE」; String c =「t」+「e」; System.out.println(a == c); // true – 2011-12-17 23:21:10

+0

Works也。所以沒有必要在池中實習字符串? – 2011-12-17 23:21:42

+3

字符串文字被自動攔截,Java編譯器將「t」+「e」編譯爲「te」。 – 2011-12-17 23:24:37

0

使用等號不會測試引用的相等性。它測試字符串內容的相等性。您需要使用==來測試引用的相等性。

要回答你的問題,不,這是不一樣的。第一個片段將兩個引用(a和b)分配給同一個字符串。第二個創建一個字符串,將其分配給a,然後實施該字符串並將該實習生池返回的字符串賦予b。 a和b因此可以引用兩個不同的String實例(當然會,因爲空字符串肯定在池中,因此intern()不會返回由a引用的STring,但會返回合併的空字符串)

0

如果該字符串值已被從不同的String實例實施,則intern()將返回先前的實例。

1

開始:"t" + "e"是一個字符串文字,因爲它會被編譯器優化。這個字符串也被用在這一行:

String a = new String("te"); 

現在,String(String)構造使得字符串的物理副本。所以,這意味着ad而不是相同的對象。

Then:String.equals(String)比較兩個字符串。它說,如果內容是平等的,而不是對象。這意味着你可能有兩個不同的字符串對象,它們具有相同的字符序列,這將使String.equals(String)返回true

String.intern()將字符串放入字符串池中,如果它尚未在其中。但是這種方法不能改變對象本身。所以這個代碼示例將打印錯誤:

String literal = "lit"; 
String nonLiteral = "abclit".substring(3); // equals "lit" 
nonLiteral.intern(); // "lit" was already in the String pool 
        // but `nonLiteral` is still `nonLiteral` 
System.out.println(literal == nonLiteral); // false 

但是,如果你這樣做:它會返回true:

String literal = "lit"; 
String nonLiteral = "abclit".substring(3); // equals "lit" 
nonLiteral = nonLiteral.intern(); // "lit" was already in the String pool and 
            // it will return the object `literal`. 
            // Now the value is replaced. 
System.out.println(literal == nonLiteral); // true 
+0

請參閱我對fge的回答的評論。 – EJP 2011-12-18 08:51:46

相關問題