首先看單個的字符串拼接:
public class Stringdeom1 {
/**
* Java8會自動對 字符串加+ 做優化,用到了Stringbuilder.
* @param args
*/
public static void main(String[] args) {
String result ="";
result += "abc";
System.out.println(result);
}
}
反編譯看看JVM指令:
#javap -c Stringdeom1.class
Compiled from "Stringdeom1.java"
public class Stringdeom1 {
public Stringdeom1();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String
2: astore_1
3: new #18 // class java/lang/StringBuilder
6: dup
7: aload_1
8: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
11: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
14: ldc #29 // String abc
16: invokevirtual #31 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: getstatic #39 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_1
27: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: return
}
可以看到在第3行生成了Stringbuilder對象,在第16行調用了append,這個很好。
在看看for循環多次拼接:
public class Stringdeom2 {
/**
* Java8會自動對 字符串加+ 做優化,用到了Stringbuilder.
* 但是對於循環好像有點處理的不好
* @param args
*/
public static void main(String[] args) {
String result ="";
for(int i=0;i<10;i++)
result += "abc";
System.out.println(result);
}
}
反編譯看看:
# javap -c Stringdeom2.class
Compiled from "Stringdeom2.java"
public class Stringdeom2 {
public Stringdeom2();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String
2: astore_1
3: iconst_0
4: istore_2
5: goto 31
8: new #18 // class java/lang/StringBuilder
11: dup
12: aload_1
13: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
16: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
19: ldc #29 // String abc
21: invokevirtual #31 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
27: astore_1
28: iinc 2, 1
31: iload_2
32: bipush 10
34: if_icmplt 8
37: getstatic #39 // Field java/lang/System.out:Ljava/io/PrintStream;
40: aload_1
41: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
44: return
}
可以看到第5行跳轉到31行,在第32行與數字10作比較,第34行決定是否跳轉到第8行繼續循環。
但是第8行才new了一個StringBuilder,這個相當於循環一次創建一個新的Stringbuilder對象,優化不算徹底。
<end>