大家都知道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. What and How in an Application

    Basically, two concerntrations: 1. What: business docs and prototype design 2. How: technical docs a ...

  2. [LeetCode] Largest Number 排序

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  3. CentOS 7系统添加启动项

    CentOS 7系统已经把CentOS 6的 runlevel 系统服务管理替换成了systemd.在 /etc/rc[0-6S].d 下添加启动项已经不能在系统启动的时候自动执行,需要通过新的 sy ...

  4. 牛客网 牛客小白月赛1 D.多项式乘法

    D.多项式乘法   链接:https://www.nowcoder.com/acm/contest/85/D来源:牛客网 这个题想一下就能想出来了. 代码: 1 #include<iostrea ...

  5. Jmeter(五十)_性能测试模拟真实场景下的用户操作

    概述 我们在做性能测试的时候,不同的视角看到的结果都不一样. 例如响应时间 用户通过客户端向服务端发出请求的时间为: T1服务端接收到请求,处理该请求的时间为:T2服务端返回数据给客户端时间为: T3 ...

  6. ZOJ 1232 Adventure of Super Mario (Floyd + DP)

    题意:有a个村庄,编号为1到a,有b个城堡,编号为a+1到a+b.现在超级玛丽在a+b处,他的家在1处.每条路是双向的,两端地点的编号以及路的长度都已给出.路的长度和通过所需时间相等.他有一双鞋子,可 ...

  7. Jenkins内存溢出的处理方法

    参考:http://openwares.net/java/jenkens_deploy_to_tomcat_error_of_outofmemoryerror.html上的说明,有如下解释: -Xms ...

  8. gitlab gitlab runner

    1.安装gitlab https://about.gitlab.com/installation/#ubuntu 2.安装runner https://docs.gitlab.com/runner/i ...

  9. PROFILE - 库存:物料状态支持 控制【物料状态定义】禁止的事务处理

    PROFILE 库存:物料状态支持

  10. C# 导出 数据 到Excel

    /// <summary> /// 实现将数据导出至Excel, /// 在上面的代码中,我们首先将gridview绑定到指定的数据源中,然后在button1的按钮(用来做导出到EXCEL ...