首先说明:
至于是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) ;,可以进一步减少空间占用,提高性能!