說你有三根弦,將兩個字符串與「==」進行比較:它何時可以工作?
String s1 = "string one";
String s2 = new String("string one");
String s3 = "string one";
我知道這是事實,s1 == s2
是false
,但我讀的地方,s1 == s3
是true
。它是否正確?爲什麼或者爲什麼不?
說你有三根弦,將兩個字符串與「==」進行比較:它何時可以工作?
String s1 = "string one";
String s2 = new String("string one");
String s3 = "string one";
我知道這是事實,s1 == s2
是false
,但我讀的地方,s1 == s3
是true
。它是否正確?爲什麼或者爲什麼不?
字符串文字自動扣留。因此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最初是在堆中創建的。
我相信這只是一個真正的編譯單位?也就是說,我不相信更一般的:'A.x == B.x'必然是真的。 – 2011-09-20 02:17:47
-1爲誤導,毫無意義的第一句話,並沒有提到字符串實習。 –
@pst:String interning適用於所有類。 –
是的,這是真的,因爲字符串文字都拘留。閱讀String.intern()
的文檔瞭解更多詳情。
因此,這些都是相同的對象(以及將相當於與==
):上述
s1
s3
s1.intern()
s2.intern()
s3.intern()
是HOW。
,你應該知道爲什麼。
通過方法參照在編譯時裁判恆定在常量池中
B)串varaible結果聲明A)串varaible到在堆空間對象。
這一切,因爲JVM specfication和它的內存設計。
A)是因爲字符串是不可變的。當java編譯class和jvm load class時,jvm發現一個String變量是由你在編碼時聲明的,因爲它是常量,jvm把常量放到「Runtime Constant Pool」內存區。而且,常量是獨一無二的。
B)是verysimple。因爲jvm運行時變量使用堆空間。
無論是與否可能是短暫的利益,但是你不應該這樣做。'=='用於_object標識,_不是字符串比較。 – paxdiablo
@paxdiablo:如果你專門處理字符串文字,可以使用'=='。但是必須記錄這一點通常是一件很痛苦的事情,所以在整個電路板上使用'equals()'會更容易。 –
是的,我知道這一切。我一直在java編程多年,只是想知道:)。它似乎不應該是這樣的... –