2017-07-18 133 views
3

問題1的java字符串連接和實習

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 

在第一種情況下,據我所知,它是兩個字符串文字的串聯,這樣的結果:「我愛的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。這是爲什麼?

+2

我們從來沒有真正比較使用==操作符串並使用.equals方法,而不是 –

+1

@JoeyPinto OP使用''==瞭解Java的內部,發現行爲看起來很奇怪,但有一個合理的解釋。 – dasblinkenlight

回答

4

你問題的第一部分是簡單的:Java編譯器會將多個字符串文字的串聯爲一個字符串字面量,即

"I Love" + " Java" 

"I Love Java" 

兩個相同的字符串文字,得到適當的實習。

同樣的實習行爲確實適用於+=操作的字符串,所以b1b2在運行時實際構建。

第二部分更棘手。回想一下,b1.intern()可能會返回b1或與其等效的某個其他String對象。當您保留a1a2時,您將a1撥回b1.intern()。當您註釋掉a1a2時,沒有現有的副本可以返回,因此b1.intern()本身可讓您返回b1

+0

我想我現在明白了。謝謝@dasblinkenlight! – wli75

1

從實習生()文檔

所有文字字符串和字符串值常量表達式拘留。字符串文字在Java™語言規範的第3.10.5節中定義。

而且從JLS 3.10.5

  • 字符串由常量表達式(§15.28)來計算在 編譯時被計算並然後進行處理,好像他們是文字。
    • 在運行時通過串聯計算的字符串是新創建的,因此它們是不同的。

你串B1實際上沒有拘留。因此有所不同。

+0

感謝您指點我的相關文檔! – wli75

0

回答問題1:

你不能==比較兩個字符串。==比較兩個原始數據類型(int,long,float,double和boolean)或對象引用。這意味着如果參考變量(a1,a2,b1,b2)不具有相同的參考(意味着它們不指向存儲器中的同一個對象),則不等於(與==比較)。

如果您將與b1.equals(b2)進行比較,則表達式爲真,因爲對象的數據是相同的。

在第一種情況下,Java在將字符串分配給某些內存之前(甚至在編譯之前)就足夠聰明,這意味着兩個字符串都存儲在相同的地址。因此,變量a1和a2引用相同的對象並且相等(==)。

在第二種情況下,您首先爲變量賦予不同的值(與第一種情況不同)。這意味着他們在內存中獲得一個單獨的地址。即使您更改值以使它們相同,地址也不會更改,並且與==的比較計算結果爲false。這在運行時發生。

至於問題2:@dasblinkenlight已經給出了很好的答案。