2013-03-15 77 views
5

所有, 我遇到一個問題,當一個寫下面一個關於Java字符串文字池中,並串的串聯混亂

String hello = "Hello"; 
String str5 = "Hel" + "lo"; 
String str8 = "Hel"; 
String str9 = "lo"; 
String str10 = str8 + str9; 
System.out.println("str10==hello?" + (str10 == hello)); 
System.out.println("str5==hello?" + (str5 == hello)); 
System.out.println("str10==str5?" + (str10 == str5)); 

然後我跑我的代碼,並在控制檯打印代碼這個

str10 == hello ? false 
str5 == hello ? true 
str10 == str5 ? false 

這使我困惑不已。爲什麼第二次打印TRUE但第一次打印FALSE? 在我理解的字符串文字池中,當定義一個字符串時,JVM將檢查該池是否包含該字符串,如果沒有,則將該字符串放入池中。
在我的代碼,可變你好存在串池,」 直升機‘和’LO‘也是在游泳池,我的問題是

  1. 如果’直升機拼接的結果「和」lo「存在於池中。
  2. 關於str5和str10s的定義和它們爲什麼不是「==」有什麼區別? ?不STR5和str10指有多種不同的「你好」,在字符串池(‘==’似乎意味着引用是同一個對象)

我的JDK版本:1.6.0_29
我IDE:IntelliJ IDEA的11.2

任何人都可以指出來非常感謝你

回答

7

它的行爲,因爲它應該它是在JLS的兩個部分不客氣

JLS #3.10.5:。

作爲常量表達式(§15.28)的值的字符串 - 使用方法String.intern「共享」以便共享唯一實例。

JLS #15.28列出了什麼被認爲是一個常量表達式。特別是,字符串文字是常量表達式(「Hel」和「lo」),但是對於一個被認爲是常量的變量,它需要是最終的。

在你的情況,如果你改變你的代碼稍微做str8str9不變,你會得到true三次:

final String str8 = "Hel"; 
final String str9 = "lo"; 
+0

謝謝你!這對我很有幫助 – fuye 2013-03-15 10:58:51

-1

如果妳比較兩個字符串使用string.equalsstring1 == string2

試試吧:

System.out.println("str10==hello?" + (str10.equals(hello)); 
+0

是的,正如我們在String equals源代碼中看到的那樣,首先檢查(this == anObject){return true;},然後判斷它是否是String的實例,如果是,則比較內容兩個字符串對象。 – fuye 2013-03-15 10:53:25

0

該代碼有以下幾點考慮:

String hello = "Hello"; 

這裏的「Hello」是分配給參考你好從而字面有它自己的哈希碼文字

String str5 = "Hel" + "lo"; 

這裏「赫爾」 +「LO」是2個文字組合並分配給參考你好從而新的文字是相同的第一個,因此相同的散列碼

String str8 = "Hel"; 
String str9 = "lo"; 

這裏STR8 + STR9是2名的引用,其結合並指向一個新的參考你好從而新的文字有它自己的哈希碼

String str10 = str8 + str9; 
System.out.println("str10==hello?" + (str10 == hello)); 
System.out.println("str5==hello?" + (str5 == hello)); 
System.out.println("str10==str5?" + (str10 == str5)); 

當您使用==它通過散列碼和值匹配。從而失配。

嘗試使用

string_1.equals(STRING_2)

代替

STRING_1 == STRING_2

,您將獲得價值僅匹配。因此,所有真

請同時參閱下面的答案(來自What is the difference between == vs equals() in Java?):

的equals()方法比較「值」 String實例內側(堆)無關如果兩個(2)對象的引用指到相同的字符串實例或不。如果任何兩個(2)類型爲String的對象引用指向相同的String實例,那麼太棒了!如果兩(2)個對象引用引用了兩(2)個不同的String實例,那麼它沒有區別。它是每個正在比較的字符串實例中的「值」(即:字符數組的內容)。

另一方面,「==」運算符比較兩個對象引用的值,以查看它們是否引用相同的String實例。如果兩個對象引用的值「引用」相同的String實例,那麼布爾表達式的結果將爲「true」.. duh。另一方面,如果兩個對象引用的值「引用」不同的String實例(即使兩個String實例具有相同的「值」,即每個String實例的字符數組的內容相同),布爾表達式的結果將是「false」。

+1

對不起,我不明白「使用==它匹配哈希碼和值」,
我打印str5,str8,str9,str10的每個哈希碼是hello.hash-> 69609650; str8.hash-> 72431; str9.hash-> 3459; str10.hash-> 69609650; str5.hash-> 69609650;我們可以看到,str5,str10的hashcode完全相同,但str5 == str10返回false; – fuye 2013-03-15 10:34:07

+0

請檢查編輯答案 – 2013-03-15 11:29:23

+0

感謝您花時間寫這this.this弄清楚「==」和「等於」之間的混淆。非常感謝 – fuye 2013-03-20 06:52:20

0
String hello = "Hello";  // at compile time string is known so in String Constant Pool 

String str5 = "Hel" + "lo"; // at compile time string is known so in String Constant Pool same object as in variable hello 

String str8 = "Hel";   // at compile time string is known so in String Constant Pool 

String str9 = "lo";   // at compile time string is known so in String Constant Pool 

String str10 = str8 + str9; // at runtime don't know values of str8 and str9 so in String Constant Pool new object different from variable hello 

str10 == hello ? false  // as str10 has new object and not the same as in hello 

str5 == hello ? true   // both were created at compile time so compiler know what's the result in str5 and referenced the same object to str5 as in hello 

str10 == str5 ? false   // str10 is a different object, hello and str5 are referenced same object as created at compile time.