StringBuilder sb = new StirngBuilder();
sb.append("a").append("b").append("c").append("d");String str = "";
str += "a";
str += "b";
str += "c";
str += "d";
在上面的例子中,“a”、“b”、“c”、“d”都应该会首先在常量池中分配空间吧,这样上面两端代码就应该差不多啊,但为什么是第一段代码效率更高呢?求解释

解决方案 »

  1.   

    str += "a"; 你要分解来看:
    str = str + "a";而str + "a" 会创建一个新的String对象,就慢了。你要知道String对象一旦创建就是不能被改变的,要达到字符串拼接的效果,就得不停创建新对象。StringBuilder直到最后sb.toString()才会创建String对象,之前都没有创建新对象(在你的例子中是的,但是如果你append的总长度超过一定范围——默认是16——就会创建一个新的数组,来装下更多的String)
      

  2.   


    JAVA中创建的String是不是都是放常量池中啊?比如sb.append("a")中的“a”是不是在常量池中占了空间的啊?
      

  3.   

    “a”是占了,"ab"没占啊,所以"ab"在"a"+"b"的时候是新建的,而sb.append("a").append('b")则没有
      

  4.   

    StringBuilder和StringBuffer,字符串是存放在char[]中的,char[]是存放在堆中的。
    相比String每次+都重新创建一个String对象,重新开辟一段内存不同,StringBuilder和StringBuffer的append都是直接把String对象中的char[]的字符直接拷贝到StringBuilder和StringBuffer的char[]上,效率比String的+高得多。当然,当StringBuilder和StringBuffer的char[]长度不够时,也会重新开辟一段内存。另外,StringBuffer是线程安全的,StringBuilder不是线程安全的。
      

  5.   


    也就是说 快得原因就是因为StringBuilder预先开辟了空间, append的时候只是向内存地址赋值; 而String总要不断的现开辟空间. 也因此String占的空间也会相对大一些! ? 
      

  6.   

    不止,每次String变动,还会重现创建String对象,而创建新的对象时,有可能会触发GC
      

  7.   

    javac会把 str += "b"; 变成一个StringBuilder的append 操作。
    相当于一个 new StringBuilder().append("a").append("b").toString().比自己调用append费事多了。
            StringBuilder builder = new StringBuilder("a");
            String s = builder.append("b").append("c").append("d").toString();        String a = "a";
            a += "b";
            a += "c";
            a += "d";
    javap -c 的输出:
        Code:
           0: new           #2                  // class java/lang/StringBuilder
           3: dup
           4: ldc           #3                  // String a
           6: invokespecial #4                  // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
           9: astore_1
          10: aload_1
          11: ldc           #5                  // String b
          13: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          16: ldc           #7                  // String c
          18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          21: ldc           #8                  // String d
          23: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          26: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          29: astore_2
          30: ldc           #3                  // String a
          32: astore_3
          33: new           #2                  // class java/lang/StringBuilder
          36: dup
          37: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
          40: aload_3
          41: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          44: ldc           #5                  // String b
          46: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          49: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          52: astore_3
          53: new           #2                  // class java/lang/StringBuilder
          56: dup
          57: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
          60: aload_3
          61: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          64: ldc           #7                  // String c
          66: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          69: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          72: astore_3
          73: new           #2                  // class java/lang/StringBuilder
          76: dup
          77: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
          80: aload_3
          81: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          84: ldc           #8                  // String d
          86: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          89: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          92: astore_3
          93: return
      

  8.   

    个人理解和1楼差不多,"ab"在"a"+"b"的时候是新建的