首先放一段代码,大家猜猜下面的两个方法有什么区别?
public class StringTest {
public void tests(String a1,String a2) {
String a = a1+ a2;
}
public void testsb(String a1,String a2) {
String a = new StringBuilder().append(a1).append(a2).toString();
}
}
复制代码
以前学习的知识告诉我们,字符串的拼接最好使用 StringBuilder 和 StringBuffer 来进行,这样可以避免重复生成字符串的成本。
这里我们打破砂锅问到底,使用 jdk 的反编译工具 javap 来看一下两者的代码有什么区别。
javap -l -c -s StringTest
Compiled from "StringTest.java"
public class StringTest {
public StringTest();
descriptor: ()V
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public void tests(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;Ljava/lang/String;)V
Code:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
18: astore_3
19: return
LineNumberTable:
line 3: 0
line 4: 19
public void testsb(java.lang.String, java.lang.String);
descriptor: (Ljava/lang/String;Ljava/lang/String;)V
Code:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
18: astore_3
19: return
LineNumberTable:
line 7: 0
line 8: 19
}
复制代码
从上述结果可以看到,对于 tests 方法,在 javac 编译后,就自动转换成了 StringBuilder 对象,同时调用了两次 append 来拼接字符串,其编译后的字节码和 testsb 方法的字节码一摸一样。
读者朋友感兴趣的话可以自己动手测试一下,需要注意的是,笔者的测试环境为 jdk8.
现在留给大家一个思考题,既然 javac 编译时,就会自动把 String 的拼接转换为 StringBuilder, 那么我们还有必要在代码中使用 StringBuilder 来替换 String 进行拼接的提效吗?
感兴趣的同学可以评论区留言讨论。
评论