2011-05-06 93 views
4

這會創建多少個字符串?Java字符串優化

String test(String text) { 
    return "string 1 " + 
    text + " string 2 " + 
    "string 3"; 
} 
+0

動機是什麼?這是面試問題還是什麼? – leonbloy 2011-05-06 13:36:46

+3

哪個版本的Java?我相信多年來編譯器已經進行了優化,這改變了字符串聯合的性能,因此答案會有所不同。 – Codemwnci 2011-05-06 13:37:50

+1

一,只有一個 – MeBigFatGuy 2011-05-06 13:38:19

回答

6

沒有新的串的呼叫都存在這裏,存在的只有一個是在StringBuilder.toString,所以

java.lang.String test(java.lang.String); 
    Code: 
    Stack=3, Locals=2, Args_size=2 
    0: new #16; //class java/lang/StringBuilder 
    3: dup 
    4: ldC#18; //String string 1 
    6: invokespecial #20; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    9: aload_1 
    10: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    13: ldC#27; //String string 2 
    15: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    18: ldC#29; //String string 3 
    20: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    23: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    26: areturn 
-1

這是

(new StringBuilder((new StringBuilder((new StringBuilder("String 1")).append(text).toString())).append("string 2 ").toString()).append("string 3").toString(); 

這3個stringbuilders和6串的等效。優化這個問題的方法是:

StringBuilder sb = new StringBuilder("string 1"); 
    sb.append(test); 
    sb.append(" string 2 "); 
    sb.append("string 3"); 
    return sb.toString(); 
+0

我只計算1個字符串,此方法'創建',其他字符串是在類加載時創建的,而不是由於此方法。 – MeBigFatGuy 2011-05-06 13:39:57

+2

這是完全不真實的。只有一個'StringBuilder'被構造,並且爲每個後續字符串調用'append'。您顯示的「優化」代碼實際上就是編譯器發出的代碼。使用'javap -c'檢查它。 – 2011-05-06 13:43:29

+0

@ gabuzo:*所有* JDKs *總是*做到這一點;他們一直都很聰明,可以在一行中使用「append」進行連接。它在循環中連接多個語句,這始終是bugbear。 – 2011-05-06 13:48:20

4

這是很容易通過編譯代碼,然後用javap -c檢查字節碼來回答。在這種特殊情況下,編譯器應該產生這樣

String result = new StringBuilder("string1"). 
    append(text).append("string2").append("string3").toString(); 

代碼,所以這取決於你如何看待它,你可能會說只有一個,或者如果你是誰喜歡數文字作爲其中的一個人「創造「,當他們使用,你可以說四。

+0

,如果你看看編譯的代碼,你會看到_NO_新的字符串調用。 (只有一個發生在StringBuilder.toString()) – MeBigFatGuy 2011-05-06 13:45:55

3

javap是你的朋友。我把你的代碼S.java和使用javap -c S deassembled它:

Compiled from "S.java" 
public class S extends java.lang.Object{ 
public S(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public java.lang.String test(java.lang.String); 
    Code: 
    0: new  #2; //class java/lang/StringBuilder 
    3: dup 
    4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V 
    7: ldc  #4; //String string 1 
    9: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    12: aload_1 
    13: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    16: ldc  #6; //String string 2 
    18: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    21: ldc  #7; //String string 3 
    23: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    26: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    29: areturn 

} 

隨着OpenJDK的1.6.0_22只有一個StringBuilder的,一個字符串創建。