2015-12-22 127 views
1

能否請你幫我理解,如果最終變量在字符串連接使用會發生什麼? 這是一個認證的問題,所以不是一個關於如何比較字符串的問題瞭解Java最終變量

String var1 = "varan";  
String an = "an"; 
final String an2 = "an"; 
System.out.println(var1 == ("var"+an));  
System.out.println(var1 == ("var"+an2)); 

輸出:

false 
true 
+3

這有什麼做用'final'。 –

+4

@MadPhysicist我相信他們的問題是關於爲什麼與'final'值連接導致與字面值相同的'String',當與非'final'值連接時不會。 – resueman

+1

'final'可能會阻止字符串interning,但我不確定它是否能夠保證,因爲您將字符串添加到一起以創建新字符串。 –

回答

2

TL; DR

因爲"var"+an是不同的StringObject新期間運行時創建"var"+an2是編譯時間常數是在並且引用var1引用的地址。


請考慮以下與您的代碼類似的示例。

public class TestString { 

    public static void main(String[] args) { 
     String stackOverflow = "stackOverflow"; 
     String overflow = "Overflow"; 

     final String overflowFinal = "Overflow"; 

     if (overflow == overflowFinal) { 
      System.out.println("Both overflows are same!"); 
     } 

     if (stackOverflow == ("stack" + overflow)) { 
      System.out.println("Stack and overflow have same reference !"); 
     } 

     if (stackOverflow == ("stack" + overflowFinal)) { 
      System.out.println("Stack and overflowFinal have same reference !"); 
     } 
    } 

} 

它會給下面的輸出:

所有的
Both overflows are same! 
Stack and overflowFinal have same reference ! 

首先請注意,==比較的Strings和引用而不是實際值。

JLS 15.18.1指出,

字符串連接的結果是至是兩個操作數串的級聯字符串對象的引用。左手操作的字符先於創建的字符串在右側操作數的字符。

的字符串對象創建(§12.5)除非表達式是一個常量表達式(§15.28)。

所以,從以上表述可以說"stack" + overflow將類似於String newString = new String("stackOverflow");(內部編譯將使用StringBuilder執行此連接)。

對於finalStringJLS 4.12.4狀態,

原始類型或類型String的變量,即final並用編譯時間常數表達式(§15.28)初始化,被稱爲常量變量。

§15.28

常量表達式是表示原語類型的值或一個String不突然完成並且使用僅由以下的表達式:

...

  • 加法運算符+-

...

編譯時String類型的常量表達式始終爲「實習」以便共享獨特實例,使用該方法String.intern

現在,上述聲明說,如果我們聲明String作爲final,它最終變成常量表達式

請注意String字面值也會被屏蔽。

實習String意味着,如果你正在創建的String和一個String具有相同內容(.equals()方法檢查),它已經存在於內存中,然後它不會產生新的String但會參考相同的內存位置。

例如,

String a = "test";//String literals 
String b = "test"; 
System.out.println("Is a & b interned ? :"+(a == b)); 

輸出:

Is a & b interned ? : true 
+1

字符串文字*總是*實施,無論「final」。由'var1'和'an'引用的文字也被禁用,這樣你的答案的一部分就不會解釋。 – EJP

+0

你的推理依然不健全。常量字符串表達式是實現的,只包含最終字符串變量或文字的字符串表達式是常量。 – EJP