String连接操作比StringBuffer产生更多的对象吗?

2014-11-23 23:19:11 · 作者: · 浏览: 1
前天写了一篇文章 Java性能陷阱:StringBuffer的性能真的比String好吗?,有两位网友进行了评论,而且看到得到了三张反对票,因此感觉有必要进行更深入的说明和研究。针对网友评论中提到的字符串直接连接操作会产生更多的垃圾对象的问题并联想到那篇文章的缘起文章( 使用String还是StringBuffer (cherami))中提到的反编译类文件的技巧,感觉可以实际的验证一下,因此又做了如下的测试。

第一步,准备工作


为了方便后面测试工作的进行,有必要编写一个简单的脚本:
echo test by jdk1.2.2
/opt/java/jdk1.2.2/bin/javac StringCompileTest.java
/opt/java/jdk1.2.2/bin/javap -c StringCompileTest
echo test by jdk1.3.1_09
/opt/java/jdk1.3.1_09/bin/javac StringCompileTest.java
/opt/java/jdk1.3.1_09/bin/javap -c StringCompileTest
echo test by jdk1.4.2
/opt/java/jdk1.4.2/bin/javac StringCompileTest.java
/opt/java/jdk1.4.2/bin/javap -c StringCompileTest

上面的脚本根据需要可以应用在windows或者linux上,我是在linux进行测试的,因此我把它保存为一个文件stringdecompile.sh,如果你在windows上测试,你可以保存为stringdecompile.bat。

第二步,测试代码


  1. public class StringCompileTest {
  2. String s1="This is a ";
  3. String s2="string decompile ";
  4. String s3="testing.";
  5. public void stringTest() {
  6. String s=s1+s2+s3;
  7. }
  8. public void stringBufferTest() {
  9. StringBuffer buffer=new StringBuffer();
  10. buffer.append(s1);
  11. buffer.append(s2);
  12. buffer.append(s3);
  13. String s=buffer.toString();
  14. }
  15. }

运行结果:
test by jdk1.2.2
Compiled from StringCompileTest.java
public class StringCompileTest extends java.lang.Object {
java.lang.String s1;
java.lang.String s2;
java.lang.String s3;
public StringCompileTest();
public void stringBufferTest();
public void stringTest();
}

Method StringCompileTest()
0 aload_0
1 invokespecial #8
4 aload_0
5 ldc #1
7 putfield #12
10 aload_0
11 ldc #2
13 putfield #13
16 aload_0
17 ldc #3
19 putfield #14
22 return

Method void stringBufferTest()
0 new #7
3 dup
4 invokespecial #9
7 astore_1
8 aload_1
9 aload_0
10 getfield #12
13 invokevirtual #11
16 pop
17 aload_1
18 aload_0
19 getfield #13
22 invokevirtual #11
25 pop
26 aload_1
27 aload_0
28 getfield #14
31 invokevirtual #11
34 pop
35 aload_1
36 invokevirtual #15
39 astore_2
40 return

Method void stringTest()
0 new #7
3 dup
4 aload_0
5 getfield #12
8 invokestatic #16
11 invokespecial #10
14 aload_0
15 getfield #13
18 invokevirtual #11
21 aload_0
22 getfield #14
25 invokevirtual #11
28 invokevirtual #15
31 astore_1
32 return
test by jdk1.3.1_09
Compiled from StringCompileTest.java
public class StringCompileTest extends java.lang.Object {
java.lang.String s1;
java.lang.String s2;
java.lang.String s3;
public StringCompileTest();
public void stringTest();
public void stringBufferTest();
}

Method StringCompil