当前位置:编程学习 > JAVA >>

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

前天写了一篇文章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 <Method java.lang.Object()>
   4 aload_0
   5 ldc #1 <String "This is a ">
   7 putfield #12 <Field java.lang.String s1>
  10 aload_0
  11 ldc #2 <String "string decompile ">
  13 putfield #13 <Field java.lang.String s2>
  16 aload_0
  17 ldc #3 <String "testing.">
  19 putfield #14 <Field java.lang.String s3>
  22 return
 
Method void stringBufferTest()
   0 new #7 <Class java.lang.StringBuffer>
   3 dup
   4 invokespecial #9 <Method java.lang.StringBuffer()>
   7 astore_1
   8 aload_1
   9 aload_0
  10 getfield #12 <Field java.lang.String s1>
  13 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
  16 pop
  17 aload_1
  18 aload_0
  19 getfield #13 <Field java.lang.String s2>
  22 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
  25 pop
  26 aload_1
  27 aload_0
  28 getfield #14 <Field java.lang.String s3>
  31 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
  34 pop
  35 aload_1
  36 invokevirtual #15 <Method java.lang.String toString()>
  39 astore_2
  40 return
 
Method void stringTest()
   0 new #7 <Class java.lang.StringBuffer>
   3 dup
   4 aload_0
   5 getfield #12 <Field java.lang.String s1>
   8 invokestatic #16 <Method java.lang.String valueOf(java.lang.Object)>
  11 invokespecial #10 <Method java.lang.StringBuffer(java.lang.String)>
  14 aload_0
  15 getfield #13 <Field java.lang.String s2>
  18 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
  21 aload_0
  22 getfield #14 <Field java.lang.String s3>
  25 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
  28 invokevirtual #15 <Method java.lang.String toString()>
  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
补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,