大家都知道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:17735
StringBuilder:6
StringBuffer: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

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

  1. String str=new String("a")和String str = "a"有什么区别?

    问:String str=new String("a")和String str = "a"有什么区别? 答:String str = "a" ...

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

    百度的面试官问 String A="ABC"; String B=new String("ABC"); 这两个值,A,B 是否相等,如果都往HashSet里面放 ...

  3. Java中String str=new String("a")和String str = "a"有什么区别?

    Q: String A="ABC"; String B=new String("ABC"); 这两个值,A,B 是否相等,如果都往HashSet里面放,能放下吗 ...

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

    本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html  版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...

  5. StringBuffer的append方法比“+”高效

    在字符串的连接过程中StringBuffer的效率要比String高: string操作代码: String str = new String("welcome to "); st ...

  6. StringBuilder、StringBuffer和String三者的联系和区别

    String 类    String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间.    String a = "a ...

  7. String类、StringBuilder类、StringBuffer类

    String类是不可变类,创建了一个String对象后,该String对象中的字符序列不能被改变. StringBuilder是字符序列可变的字符串类,提供了一系列修改字符串的方法. StringBu ...

  8. JAVA String、StringBuilder、和StringBuffer的区别,及如何使用

    目录 String类 一.String类的理解和创建对象 二.String类创建的方式 两种创建String对象的区别 测试题 三.String常用方法 四.StringBuffer类 1.Strin ...

  9. StringBuilder的构造方法和append方法

    Java中StringBuilder的构造方法 StringBuilder构造方法: public StringBuilder(): 创建一个空白可变的字符串对象,不含有任何内容 public Str ...

随机推荐

  1. VUE 使用中踩过的坑

    vue如今可谓是一匹黑马,github star数已居第一位!前端开发对于vue的使用已经越来越多,它的优点就不做介绍了,本篇是我对vue使用过程中以及对一些社区朋友提问我的问题中做的一些总结,帮助大 ...

  2. android基本控件学习-----ProgressBar

    ProgressBar(进度条)讲解 一.常用属性和基础使用实例 (1)常用属性: android:max:进度条的最大值 android:progress:进度条已完成进度值 android:pro ...

  3. 老郭带你学数据结构(C语言系列)2-线性表之动态顺序表

    一.基本概念: 线性表:由n个类型相同的数据元素组成的有限序列,记为(a1,a2,--an). 线性表的特征:其中的元素存在这序偶关系,元素之间存在着严格的次序关系. 顺序存储表:线性表中的元素依次存 ...

  4. hdu 1005(找循环节)

    Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. Linux一些防攻击策略

    来自http://www.imooc.com/learn/344

  6. 将Map<String, List<Map<String,Object>>>进行排序

    首先我贴上我的代码,刚开始我也不知道怎么排序还写了一些方法,最后请教群里的大神解决了 public Map<String, List<Map<String,Object>> ...

  7. NBNS扫描工具nbtscan-unixwiz

    NBNS扫描工具nbtscan-unixwiz NBNS是NetBIOS Name Service的缩写,表示NetBIOS名称解析服务.NETBIOS是一种网络协议,用于实现消息通信和资源共享.利用 ...

  8. mysql事物隔离级别

    mysql实现了四种隔离级别 Read Uncommitted(未提交读) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取 ...

  9. kafka消费者客户端

    Kafka消费者 1.1 消费者与消费者组 消费者与消费者组之间的关系 ​ 每一个消费者都隶属于某一个消费者组,一个消费者组可以包含一个或多个消费者,每一条消息只会被消费者组中的某一个消费者所消费.不 ...

  10. delphi如何把一个整数转化为4个十六进制字节

    var   s:string;   len:Integer;   AData:TBytes; begin        s:=IntToHex(149259,6);//返回6位字符串     len  ...