簡體   English   中英

關於Java String文字池和String的串聯的混淆

[英]a confusion about java String literal pool and String's concatenation

所有,當我寫下面的代碼時,我遇到了一個問題

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? 在我理解String文字池時,當定義了一個字符串時,JVM將檢查該池是否包含該字符串,如果不包含該字符串,則將該字符串放入池中。
在我的代碼中,字符串池中存在變量hello ,池中也存在“ Helo ”和“ lo ”,我的問題是

  1. 如果池中存在“ Helo ”和“ lo ”的並置結果。
  2. 關於str5和str10s的定義之間有什么區別,為什么它們不是“ ==”? str5和str10是否引用字符串池中不同的“ Hello ”?(“ ==”似乎表示引用是同一對象)

我的jdk版本:1.6.0_29
我的IDE:Intellij Idea 11.2

有人可以指出嗎? 非常感謝你

它的行為應有。 JLS分為兩個部分。

JLS#3.10.5

使用String.intern方法,對作為常量表達式(第15.28節)的值的字符串進行“ interned”,以便共享唯一的實例。

JLS#15.28列出了被視為常量表達式的內容。 特別是,字符串文字是常量表達式(“ Hel”和“ lo”),但是要使變量被認為是常量,則必須為最終變量。

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

final String str8 = "Hel";
final String str9 = "lo";
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.

該代碼需要考慮以下幾點:

String hello = "Hello";

這里“ Hello”是分配給引用hello的文字,因此該文字具有自己的哈希碼

String str5 = "Hel" + "lo";

這里“ Hel” +“ lo”是2個文字,它們組合並分配給引用hello,因此新文字與第一個文字相同,因此哈希碼也相同

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

這里str8 + str9是2個引用,它們組合並指向一個新引用hello,因此新文字具有其自己的哈希碼

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)

代替

字符串_1 ==字符串_2

您將只獲得價值匹配。 因此,一切都是真的

請也參考下面的答案(從Java中== vs equals()之間有什么區別? ):

equals()方法比較String實例內部(在堆上)的“值”,而不管two(2)對象引用是否引用相同的String實例。 如果String類型的任何兩個(2)對象引用都引用相同的String實例,那就太好了! 如果two(2)對象引用引用了two(2)個不同的String實例..則沒有任何區別。 它是被比較的每個String實例內部的“值”(即:字符數組的內容)。

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

如果u比較兩個字符串,請使用string.equals而不是string1 == string2

試試吧:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM