首先說明:
至于是StringBuilder還是StringBuffer去取代“+”,這就是實際應用場景需要考量的,看你的應用場景需要考慮線程安全性與否!
每個觀點的提出都要有理有據:
如下是兩段字元串拼接兩種實作方式:
public class TestA {
public static void main(String[] args) {
String str = "A" ;
StringBuilder sb = new StringBuilder(str) ;
sb.append("B");
sb.append("C");
System.out.println(str);
}
}
第二段:
public class TestB {
public static void main(String[] args) {
String str = "A" ;
str += "B" ;
str += "C" ;
System.out.println(str);
}
}
然後用javap去分析:
TestA的分析結果:
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String A
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: aload_1
8: invokespecial #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
11: astore_2
12: aload_2
13: ldc #5; //String B
15: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
18: pop
19: aload_2
20: ldc #7; //String C
22: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
25: pop
26: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_1
30: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
33: return
}
TestB的分析結果:
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String A
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
14: ldc #6; //String B
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: new #3; //class java/lang/StringBuilder
26: dup
27: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
30: aload_1
31: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
34: ldc #8; //String C
36: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
39: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
42: astore_1
43: new #3; //class java/lang/StringBuilder
46: dup
47: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
50: aload_1
51: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
54: ldc #9; //String D
56: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/S
tringBuilder;
59: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
62: astore_1
63: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream;
66: aload_1
67: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
70: return
}
TestA隻在第3行産生了1個StringBuilder對象,而TestB在第3,23,43産生了3個StringBuilder對象;
不論是從執行步驟複雜程度還是從StringBuilder執行個體化對象數量來講,使用StringBuilder的效率明顯高于使用“+”拼接字元串 。使用“+”拼接字元串JVM會将其轉換為StringBuilder,但是每“+”一次,就是多一個StringBuilder對象,但是使用StringBuilder拼接字元串,隻會有一個StringBuilder對象,另外注意,當使用StringBuilder拼接字元串個數大于它的容量capacity(預設是16)時,它會進行擴容,是以,在能夠能夠确定最大拼接數的情況下,在new StringBuilder()時,指定capacity-- StringBuilder sb = new StringBuilder(str,3) ;,可以進一步減少空間占用,提高性能!