2011-09-20 40 views
9

說你有三根弦,將兩個字符串與「==」進行比較:它何時可以工作?

String s1 = "string one"; 
String s2 = new String("string one"); 
String s3 = "string one"; 

我知道這是事實,s1 == s2false,但我讀的地方,s1 == s3true。它是否正確?爲什麼或者爲什麼不?

+2

無論是與否可能是短暫的利益,但是你不應該這樣做。'=='用於_object標識,_不是字符串比較。 – paxdiablo

+0

@paxdiablo:如果你專門處理字符串文字,可以使用'=='。但是必須記錄這一點通常是一件很痛苦的事情,所以在整個電路板上使用'equals()'會更容易。 –

+1

是的,我知道這一切。我一直在java編程多年,只是想知道:)。它似乎不應該是這樣的... –

回答

21

字符串文字自動扣留。因此s1 == s3是真的。字符串既可以在字符串常量池中創建,也可以在堆空間中創建。如果您在堆中創建了一個字符串,則該字符串將位於字符串常量池中。

當你創建一個字符串(字符串S1 =「串一」),該字符串在字符串常量池的創建。此外,字符串常量池不存儲重複項。所以當你說,

String s1 = "string one"; 
String s3 = "string one"; 

s1和s3都將指向字符串常量池中的同一個字符串實例。所以s1.equals(s3)將成立。而s1 == s3也是如此;因爲這兩個指針是相同的。

但是,當您使用實例化的「新」的構造

String s2 = new String("string one"); 

那麼S2的堆空間創建一個字符串。堆空間大於字符串常量池

所以不同的區域的存儲器,同時s1.equals(S2)爲真,S1 == s2爲假;因爲它們將指向不同的記憶區域。

但是,你可以轉換使用「新」的構造,使之通過調用實習生()函數移動到字符串常量池中創建一個字符串。所以s2.intern()會在字符串常量池中返回一個字符串;儘管s2最初是在堆中創建的。

+0

我相信這只是一個真正的編譯單位?也就是說,我不相信更一般的:'A.x == B.x'必然是真的。 – 2011-09-20 02:17:47

+2

-1爲誤導,毫無意義的第一句話,並沒有提到字符串實習。 –

+0

@pst:String interning適用於所有類。 –

4

是的,這是真的,因爲字符串文字都拘留。閱讀String.intern()的文檔瞭解更多詳情。

因此,這些都是相同的對象(以及將相當於與==):上述

s1 
s3 
s1.intern() 
s2.intern() 
s3.intern() 
1

是HOW。

,你應該知道爲什麼。

通過方法參照在編譯時裁判恆定在常量池中

B)串varaible結果聲明A)串varaible到在堆空間對象。

這一切,因爲JVM specfication和它的內存設計。

A)是因爲字符串是不可變的。當java編譯class和jvm load class時,jvm發現一個String變量是由你在編碼時聲明的,因爲它是常量,jvm把常量放到「Runtime Constant Pool」內存區。而且,常量是獨一無二的。

B)是verysimple。因爲jvm運行時變量使用堆空間。

相關問題