首先放一段代码,大家猜猜下面的两个方法有什么区别?
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 进行拼接的提效吗?
感兴趣的同学可以评论区留言讨论。
评论