2015-10-03 70 views
-3

我有以下代碼:爲什麼DOES ==有時適用於Java中的字符串?

Circle c1 = new Circle(); 
Circle c2 = new Circle(); 
System.out.println(c1 == c2); 

,輸出False,符合市場預期。這是因爲c1c2是引用類型,「==」檢查它們是否指向相同類型(它們不這樣做)。

不過,我最近嘗試這樣的:

String a = "hello"; 
String b = "hello"; 
System.out.println(a == b); 

由於某種原因輸出True。爲什麼是這樣?字符串是參考類型,ab指的是不同的存儲位置。我總是被教導,你需要使用.equals()這個工作,這不是!

請參見:https://ideone.com/CyjE49

UPDATE 這豈不是重複的! 我知道正確的方式來比較字符串使用.eqauls()

更新2 這個問題可能有一個答案:How do I compare strings in Java?,但問題也沒有問什麼,我問,答案就在更多的去詳細比需要。

因此,使用相同的問題進行搜索(在Google或其他平臺上)意味着用戶不會被髮送到該問題,或者可能由於問題的標題而將其完全消除。因此,爲了其他用戶的利益而保持這一點可能是一個好主意!

+1

我同意OP-這不是這些問題中的任何一個的重複。這是要求_why_引用相等不返回兩個完全相同的字符串文字。 – davmac

+2

你會在這裏找到答案http://stackoverflow.com/questions/2486191/what-is-the-java-string-pool-and-how-is-s-different-from-new-strings。 – yorlin

+0

是的,這個問題可能在那裏有答案,但是那裏的問題並沒有這麼問。因此,用同樣的問題搜索,不會發送到那裏。因此,爲了其他用戶的利益,這可能是一個想法。 –

回答

2

String interning。由於ab都是具有相同值的常量,因此編譯器利用字符串的不變性使兩個變量都引用相同的字符串,從而節省空間。因此==返回True,因爲它們實際上是相同的對象。

+0

他們是同一個對象。 「有效」是沒有必要的。 – davmac

+0

最初的印象是它們不一樣。或者,這可能只是一種糟糕的寫作習慣。 – Kyte

1

在這種情況下,「hello」被視爲分配給a和b的常量。所以這裏==實際上返回true。如果你這樣做:

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a == b); 

你會得到false

5

由於字符串文字是intern'd,相同的文字指的是同一個對象。因此,檢查它們之間的引用相等性必然會返回true。

從Java語言規範(3.10.5):

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

實際上,編譯器會將字符串文字「早期」彙集起來,並只將一個副本存儲在已編譯的.class文件中。然而,來自不同類文件的相同字符串文字仍然會使用==進行比較,因爲文字在加載類時仍然是intern'd。

如果,另一方面,我們正確地應用與圓爲String的例子中,我們將有:

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a == b); // will print false! 

在這種情況下,我們明確地創建新的對象,所以他們不能等於引用。

通過非文字或其他常量字符串表達式構造的任何字符串也不一定會將reference-equal與相同的字符串進行比較。例如:

String a = "hello"; 
String b = "hello"; 
System.out.println(a.substring(0,3) == b.substring(0,3)); // may print false! 
相關問題