[英]java string concatenation and interning
問題 1
String a1 = "I Love" + " Java";
String a2 = "I Love " + "Java";
System.out.println( a1 == a2 ); // true
String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
System.out.println( b1 == b2 ); // false
在第一種情況下,我知道它是兩個字符串文字的串聯,因此結果“I Love Java”將被保留,結果為真。 但是,我不確定第二種情況。
問題2
String a1 = "I Love" + " Java"; // line 1
String a2 = "I Love " + "Java"; // line 2
String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
String b3 = b1.intern();
System.out.println( b1 == b3 ); // false
上面返回false,但是如果我注釋掉第1 行和第2 行,它返回true。 這是為什么?
您問題的第一部分很簡單:Java 編譯器將多個字符串文字的串聯視為單個字符串文字,即
"I Love" + " Java"
和
"I Love Java"
是兩個相同的字符串文字,它們被正確地插入。
同樣的實習行為並不適用於+=
對字符串的操作,所以b1
和b2
在運行時實際構成。
第二部分比較棘手。 回想一下b1.intern()
可能會返回b1
或其他與它相等的String
對象。 當您保留a1
和a2
,您會從對b1.intern()
的調用中獲得a1
。 當您注釋掉a1
和a2
,沒有要返回的現有副本,因此b1.intern()
將返回b1
本身。
來自 intern() 文檔
所有文字字符串和字符串值常量表達式都被實習。 字符串文字在 Java™ 語言規范的第 3.10.5 節中定義。
- 由常量表達式(第 15.28 節)計算的字符串在編譯時計算,然后將它們視為文字。
- 在運行時通過連接計算的字符串是新創建的,因此是不同的。
你的字符串 b1 實際上沒有被實習。 因此差異。
問題1的答案:
您不能將兩個String與==
進行比較。 ==
比較兩種原始數據類型(int,long,float,double和boolean)或對象引用 。 這意味着如果引用變量(a1,a2,b1,b2)沒有相同的引用(意味着它們不指向內存中的同一個對象),則它們不相等(與==
比較)。
如果要與b1.equals(b2)
進行比較,則表達式將為true,因為對象的數據是相同的。
在第一種情況下,Java足夠聰明,可以在為它們分配一些內存(甚至在編譯之前)之前連接字符串,這意味着兩個字符串都存儲在同一個地址中。 因此,變量a1和a2引用相同的對象並且相等( ==
)。
在第二種情況下,首先為變量分配不同的值(與第一種情況不同)。 這意味着他們在內存中獲得了一個單獨的地址。 即使您更改了值以使它們相同,地址也不會更改,並且與==
的比較計算結果為false。 這在運行時發生。
至於問題2:@dasblinkenlight已經給出了一個很好的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.