2012-12-15 78 views
6

這是如何工作的?我似乎無法找到答案。primitive-boolean要字符串連接/轉換

boolean bool=true; 
System.out.println("the value of bool is : " + true); 
//or 
System.out.println("the value of bool is : " + bool); 
  • 有哪些東西會在幕後?
  • 布爾值如何被轉換爲字符串作爲布爾值不能隱含 類型轉換?
  • 自動裝箱/拆箱是否涉及?
  • toString()String.valueOf()這樣的方法是以某種方式參與嗎?
+2

閱讀本文:http://www.znetdevelopment.com/blogs/2009/04/06/java-string-concatenation/ –

回答

13

確切的規則是在Java語言規範拼寫,§5.1.11. String Conversion

根據這些規則,"str" + bool相當於:

"str" + new Boolean(bool).toString() 

這就是說,允許編譯器相當大的餘地究竟怎麼了評估整體表達。來自JLS §15.18.1. String Concatenation Operator +

一個實現可能選擇在一個步驟中執行轉換和連接以避免創建並丟棄中間String對象。爲了提高重複字符串連接的性能,Java編譯器可以使用類或類似技術來減少通過評估表達式創建的中間對象的數量。

對於基元類型,實現還可以通過直接從基元類型轉換爲字符串來優化封裝器對象的創建。

例如,我的編譯如下:

boolean bool = true; 
System.out.println("the value of bool is : " + bool); 

完全等同於:

boolean bool = true; 
System.out.println(new StringBuilder("the value of bool is : ").append(bool).toString()); 

他們導致相同的字節碼:

Code: 
    0: iconst_1  
    1: istore_1  
    2: getstatic  #59     // Field java/lang/System.out:Ljava/io/PrintStream; 
    5: new   #166    // class java/lang/StringBuilder 
    8: dup   
    9: ldc   #168    // String the value of bool is : 
    11: invokespecial #170    // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    14: iload_1  
    15: invokevirtual #172    // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder; 
    18: invokevirtual #176    // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    21: invokevirtual #69     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    24: return   
+1

是否確實代碼片斷創建相同的字節碼必然意味着前者被轉換爲後者?(在轉換爲字節碼之前,就是這樣) –

+0

@VinayWadhwa我不認爲JLS指定了*你應該如何實現字符串連接 - 僅僅是結果應該是什麼。然而,就我所知,Snorcle Java編譯器已經使用'StringBuffer',然後是一個'StringBuilder'來實現它。將字符串連接作爲JVM中的內部操作可能是完全允許的。 – millimoose

+0

@VinayWadhwa這似乎暗示了[§15.18.1](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.1):「爲了提高重複字符串連接的性能,Java編譯器可以使用StringBuffer類或類似的技術......「和」對於原始類型,實現也可以優化掉包裝對象的創建......「 – millimoose

2

這是一個編譯器的東西。如果連接的右操作數是一個對象,則發送該對象的方法,而如果該操作數是基元,則編譯器知道使用哪種類型特定的行爲將該基元轉換爲字符串。

+0

我看到..你能指點我的文檔說明嗎? –

+0

@VinayWadhwa:查看我的答案以供參考。 –

2

編譯器編譯它到

StringBuilder sb = new StringBuilder("the value of bool is : "); 
sb.append(true); 
System.out.println(sb.toString()); 

連接和轉換的規則在the JLS中解釋。

+0

哪個編譯器?每個編譯器? 如果你能指點我的信息的來源,它將不勝感激。 您提供的參考文獻與您的答案無關,我認爲...... –

+0

它表示:*實現可以選擇在一個步驟中執行轉換和連接,以避免創建並丟棄中間String對象。爲了提高重複字符串連接的性能,Java編譯器可以使用StringBuffer類或類似的技術來減少通過評估表達式創建的中間String對象的數量*要了解規則,請閱讀JLS。要知道它是如何工作的,請閱讀由編譯器生成的字節碼。 –