StringBuilder的append、StringBuffer的append和String str = "a"+"b"的区别?

大家都知道String+String会开销额外的系统资源,粗略的原因是String是不可变类,每一步操作都会返回新的String变量,占用空间及时间。
其实我的理解不是这样的,我们来看看String+的底层实现。

测试案例

public static void main(String[] args) {
        String a = "a";
        StringBuilder b = new StringBuilder("b");
        StringBuffer c = new StringBuffer("c");
        long star = System.currentTimeMillis();
        for(int i=0;i<200000;i++){
            a+="a";
        }
        long end = System.currentTimeMillis();
        System.out.println("String:"+(end-star));

        star = System.currentTimeMillis();
        for(int i=0;i<200000;i++){
            b.append("b");
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder:"+(end-star));

        star = System.currentTimeMillis();
        for(int i=0;i<200000;i++){
            c.append("c");
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer:"+(end-star));
    }

测试结果

String:17735StringBuilder:6StringBuffer:7

测试结论
String+ 确实占用了太多的资源,处理效率非常低下。StringBuilder比StringBuffer更新了同步方法,性能有所提升。

原因分析

我用javap -verbose 查看已经编译好的class文件发现:

public static void main(java.lang.String[]);
   flags: ACC_PUBLIC, ACC_STATIC
   Code:
     stack=6, locals=9, args_size=1
        0: ldc           #16                 // String a
        2: astore_1
        3: new           #18                 // class java/lang/StringBuilder
        6: dup
        7: ldc           #20                 // String b
        9: invokespecial #22                 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
       12: astore_2
       13: new           #25                 // class java/lang/StringBuffer
       16: dup
       17: ldc           #27                 // String c
       19: invokespecial #29                 // Method java/lang/StringBuffer."
init>":(Ljava/lang/String;)V
       22: astore_3
       23: invokestatic  #30                 // Method java/lang/System.current
imeMillis:()J
       26: lstore        4
       28: iconst_0
       29: istore        6
       31: goto          57
       34: new           #18                 // class java/lang/StringBuilder
       37: dup
       38: aload_1
       39: invokestatic  #36                 // Method java/lang/String.valueOf
(Ljava/lang/Object;)Ljava/lang/String;
       42: invokespecial #22                 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
       45: ldc           #16                 // String a
       47: invokevirtual #42                 // Method java/lang/StringBuilder.
ppend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       50: invokevirtual #46                 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
       53: astore_1
       54: iinc          6, 1
       57: iload         6
       59: ldc           #50                 // int 100000
       61: if_icmplt     34
       64: invokestatic  #30                 // Method java/lang/System.current
imeMillis:()J
       67: lstore        6
       69: getstatic     #51                 // Field java/lang/System.out:Ljav
/io/PrintStream;
       72: new           #18                 // class java/lang/StringBuilder
       75: dup
       76: ldc           #55                 // String String:
       78: invokespecial #22                 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
       81: lload         6
       83: lload         4
       85: lsub
       86: invokevirtual #57                 // Method java/lang/StringBuilder.
ppend:(J)Ljava/lang/StringBuilder;
       89: invokevirtual #46                 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
       92: invokevirtual #60                 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
       95: invokestatic  #30                 // Method java/lang/System.current
imeMillis:()J
       98: lstore        4
      100: iconst_0
      101: istore        8
      103: goto          116
      106: aload_2
      107: ldc           #20                 // String b
      109: invokevirtual #42                 // Method java/lang/StringBuilder.
ppend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      112: pop
      113: iinc          8, 1
      116: iload         8
      118: ldc           #50                 // int 100000
      120: if_icmplt     106
      123: invokestatic  #30                 // Method java/lang/System.current
imeMillis:()J
      126: lstore        6
      128: getstatic     #51                 // Field java/lang/System.out:Ljav
/io/PrintStream;
      131: new           #18                 // class java/lang/StringBuilder
      134: dup
      135: ldc           #65                 // String StringBuilder:
      137: invokespecial #22                 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
      140: lload         6
      142: lload         4
      144: lsub
      145: invokevirtual #57                 // Method java/lang/StringBuilder.
ppend:(J)Ljava/lang/StringBuilder;
      148: invokevirtual #46                 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
      151: invokevirtual #60                 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
      154: invokestatic  #30                 // Method java/lang/System.current
imeMillis:()J
      157: lstore        4
      159: iconst_0
      160: istore        8
      162: goto          175
      165: aload_3
      166: ldc           #27                 // String c
      168: invokevirtual #67                 // Method java/lang/StringBuffer.a
pend:(Ljava/lang/String;)Ljava/lang/StringBuffer;
      171: pop
      172: iinc          8, 1
      175: iload         8
      177: ldc           #50                 // int 100000
      179: if_icmplt     165
      182: invokestatic  #30                 // Method java/lang/System.current
imeMillis:()J
      185: lstore        6
      187: getstatic     #51                 // Field java/lang/System.out:Ljav
/io/PrintStream;
      190: new           #18                 // class java/lang/StringBuilder
      193: dup
      194: ldc           #70                 // String StringBuffer:
      196: invokespecial #22                 // Method java/lang/StringBuilder.
<init>":(Ljava/lang/String;)V
      199: lload         6
      201: lload         4
      203: lsub
      204: invokevirtual #57                 // Method java/lang/StringBuilder.
ppend:(J)Ljava/lang/StringBuilder;
      207: invokevirtual #46                 // Method java/lang/StringBuilder.
oString:()Ljava/lang/String;
      210: invokevirtual #60                 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
      213: return

从编译的代码来看,String+的准确操作是:
new StringBuilder()

new String.valueof()

StringBuilder.<init>

StringBuilder.append()

StringBuilder.toString()

而StringBuilder的准确操作是:

StringBuilder.append()

而StringBuffer()的准确操作是:

StringBuffer.append

转自http://alqm1314-126-com.iteye.com/blog/1932879

时间: 2024-10-08 20:36:44

StringBuilder的append、StringBuffer的append和String str = "a"+"b"的区别?的相关文章

Java中String直接赋字符串和new String的区别 如String str=new String(&quot;a&quot;)和String str = &quot;a&quot;有什么区别?

百度的面试官问 String A="ABC"; String B=new String("ABC"); 这两个值,A,B 是否相等,如果都往HashSet里面放,能放下吗? 答:A==B 不等,但是A.equals(B)相等:因为相等,所以都往HashSet里面放不下,只能放一个 这个问题涉及到常量池的概念, 问:String str=new String("a")和String str = "a"有什么区别? 答: ==与e

一大波Java来袭(四)String类、StringBuilder类、StringBuffer类对比

本文主要介绍String类.StringBuffer类.StringBuilder类的区别  : 一.概述 (一)String 字符串常量,但是它具有不可变性,就是一旦创建,对它进行的任何修改操作都会创建一个新的字符串对象. (二)StringBuffer 字符串可变量,是线程安全的,和StringBuilder类提供的方法完全相同. 区别在于StringBuffer每个方法中前面添加了"synchronized",保证其是线程安全的. (三)StringBuilder 字符串可变量,

StringBuffer类详解(String、StringBuffer、StringBuilder的区别)

StringBuffer类详解 1.类结构: ·        java.lang.Object ·        java.lang.StringBuffer ·        All Implemented Interfaces: Serializable, Appendable, CharSequence public final class StringBuffer extends Object implements Serializable, CharSequence 2.类概述: 一

java中String类、StringBuilder类和StringBuffer类详解

本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html 版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利 正文: 探秘Java中String.StringBuilder以及StringBuffer 相信String这个类是Java中使用得

JAVA中Stringbuffer的append( )方法

Stringbuffer是动态字符串数组,append( )是往动态字符串数组添加,跟“xxxx”+“yyyy”相当‘+’号. 跟String不同的是Stringbuffer是放一起的,String1+String2和Stringbuffer1.append("yyyy")虽然打印效果一样,但在内存中表示却不一样. String1+String2 存在于不同的两个地址内存,Stringbuffer1.append(Stringbuffer2)放再一起. 例如: StringBuffer

StringBuilder、StringBuffer和String三者的联系和区别(转)

StringBuilder.StringBuffer和String三者的联系和区别 1. String 类    String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间.    String a = "a"; //假设a指向地址0x0001    a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已

Java中StringBuffer类append方法的使用

Java中StringBuffer类append方法的使用 append方法的作用是在一个StringBuffer对象后面追加字符串. 例如StringBuffer s = new StringBuffer("Hello");s.append("World");则s的内容是HelloWorld

(1)String类 (2)StringBuilder类和StringBuffer类 (3)日期相关的类

1.String类(重中之重)1.1 常用的方法(练熟.记住)(1)常用的构造方法 String() - 使用无参的方式构造空字符串对象. String(byte[] bytes) - 根据参数指定的byte数组来构造对象. String(byte[] bytes, int offset, int length) - 使用bytes数组中从offset位置开始的length个字节来构造对象. String(char[] value) - 根据参数指定的char数组来构造对象. String(ch

Java基础——数组应用之StringBuilder类和StringBuffer类

一.StringBuffer类 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类. 所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入.删除等操作,使用StringBuffer要更加适合一些. 在StringBuffer类中存在很多和String类一样的方法,这些方法在功能上和String类中的功能是完全一样的