首先看单个的字符串拼接:
public class Stringdeom1 { /** * Java8会自动对 字符串加+ 做优化,用到了Stringbuilder. * @param args */ public static void main(String[] args) { String result =""; result += "abc"; System.out.println(result); } }反编译看看JVM指令:
#javap -c Stringdeom1.class Compiled from "Stringdeom1.java" public class Stringdeom1 { public Stringdeom1(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16 // String 2: astore_1 3: new #18 // class java/lang/StringBuilder 6: dup 7: aload_1 8: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 11: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 14: ldc #29 // String abc 16: invokevirtual #31 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_1 23: getstatic #39 // Field java/lang/System.out:Ljava/io/PrintStream; 26: aload_1 27: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return }可以看到在第3行生成了Stringbuilder对象,在第16行调用了append,这个很好。
在看看for循环多次拼接:
public class Stringdeom2 { /** * Java8会自动对 字符串加+ 做优化,用到了Stringbuilder. * 但是对于循环好像有点处理的不好 * @param args */ public static void main(String[] args) { String result =""; for(int i=0;i<10;i++) result += "abc"; System.out.println(result); } }反编译看看:
# javap -c Stringdeom2.class Compiled from "Stringdeom2.java" public class Stringdeom2 { public Stringdeom2(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #16 // String 2: astore_1 3: iconst_0 4: istore_2 5: goto 31 8: new #18 // class java/lang/StringBuilder 11: dup 12: aload_1 13: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 16: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 19: ldc #29 // String abc 21: invokevirtual #31 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_1 28: iinc 2, 1 31: iload_2 32: bipush 10 34: if_icmplt 8 37: getstatic #39 // Field java/lang/System.out:Ljava/io/PrintStream; 40: aload_1 41: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 44: return }可以看到第5行跳转到31行,在第32行与数字10作比较,第34行决定是否跳转到第8行继续循环。
但是第8行才new了一个StringBuilder,这个相当于循环一次创建一个新的Stringbuilder对象,优化不算彻底。
<end>
