簡體   English   中英

java字符串連接和實習

[英]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"

是兩個相同的字符串文字,它們被正確地插入。

同樣的實習行為並不適用於+=對字符串的操作,所以b1b2在運行時實際構成。

第二部分比較棘手。 回想一下b1.intern()可能會返回b1或其他與它相等的String對象。 當您保留a1a2 ,您會從對b1.intern()的調用中獲得a1 當您注釋掉a1a2 ,沒有要返回的現有副本,因此b1.intern()將返回b1本身。

來自 intern() 文檔

所有文字字符串和字符串值常量表達式都被實習。 字符串文字在 Java™ 語言規范的第 3.10.5 節中定義。

JLS 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.

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