有这么一个例子:
String a = "nihao";
String b = "1233";
int c = 21;
String res = a+b+"dd"+c;
开始我就是这样写的,然后同时看到了跟我说最好用string builder,效率高一点,然后我感觉有道理,就改了:
StringBuilder builder = new StringBuilder();
("nihao").append("1233").append(21);
但是这个时候ide提醒我如下,就是让我该回去
Reports any usages of StringBuffer, StringBuilder or StringJoiner which can be replaced with a single concatenation. Using a String concatenation makes the code shorter and simpler. This inspection only reports when the resulting concatenation is at least as efficient or more efficient than the original code.
网上重新查了查,我就重新写了个测试,验证一下不同。
test1:
public void test1(){
StringBuilder builder = new StringBuilder();
("nihao").append("1233").append(21);
(());
}
编译后:
public void test1() {
StringBuilder builder = new StringBuilder();
("nihao").append("1233").append(21);
(());
}
用builder没有什么不同。
test2:
public void test2(){
String a = "nihao";
String b = "1233";
int c = 21;
String res = a+b+"dd"+c;
String two = "dffe"+123+"ddd";
}
编译后:
public void test2() {
String a = "nihao";
String b = "1233";
int c = 21;
(new StringBuilder()).append(a).append(b).append("dd").append(c).toString();
String two = "dffe123ddd";
}
这个时候不同就多了。看一下反编译结果(javap -c ):
public void test1();
Code:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: astore_1
8: aload_1
9: ldc #4 // String nihao
11: invokevirtual #5 // Method java/lang/:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6 // String 1233
16: invokevirtual #5 // Method java/lang/:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: bipush 21
21: invokevirtual #7 // Method java/lang/:(I)Ljava/lang/StringBuilder;
24: pop
25: getstatic #8 // Field java/lang/:Ljava/io/PrintStream;
28: aload_1
29: invokevirtual #9 // Method java/lang/:()Ljava/lang/String;
32: invokevirtual #10 // Method java/io/:(Ljava/lang/String;)V
35: return
public void test2();
Code:
0: ldc #4 // String nihao
2: astore_1
3: ldc #6 // String 1233
5: astore_2
6: bipush 21
8: istore_3
9: new #2 // class java/lang/StringBuilder
12: dup
13: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
16: aload_1
17: invokevirtual #5 // Method java/lang/:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: aload_2
21: invokevirtual #5 // Method java/lang/:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: ldc #11 // String dd
26: invokevirtual #5 // Method java/lang/:(Ljava/lang/String;)Ljava/lang/StringBuilder;
29: iload_3
30: invokevirtual #7 // Method java/lang/:(I)Ljava/lang/StringBuilder;
33: invokevirtual #9 // Method java/lang/:()Ljava/lang/String;
36: astore 4
38: ldc #12 // String dffe123ddd
40: astore 5
42: return
最后,再结合网上的其他测试,有以下几点:
1、如果+拼接的时候没有对象,比如String two = "dffe"+123+"ddd";
,这种情况效率最高,不要画蛇添足的非要用string builder。你看编译后的结果,JVM直接就做了拼接转化,根本不用builder.
2、如果你要拼接的包含对象,比如String res = a+b+"dd"+c;
,而且不用于循环,这个时候用+ 和 用builder 随意,都一样。
3、一行 + 操作就会产生一个builder(当然,分号结尾才是一行)。比如String res = a+b+"dd"+c; res += "555";
会new 两次builder。这和用在循环一个道理,同样每次循环都会重新new一个builder。所以用在循环或者多行操作的时候,builder是效率最高的,次数少的话和buffer是差不多的。