日期:2014-05-20  浏览次数:20761 次

一些字符串追加的问题(+操作符和append)。
麻烦先看看我整理的笔记,问题在后面,如果笔记有错请前辈们一定指出来,谢谢了!

======================================================================
String   str1   =   "a ";
String   str2   =   "b ";
String   str3   =   str1   +   str2;
======================================================================
这里str3的赋值过程不是表面上看起来的那么简单。我们来看看它的字节码:
======================================================================
      L2   (6)
        LINENUMBER   9   L2
        NEW   java/lang/StringBuilder
        DUP
        ALOAD   1
        INVOKESTATIC   java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
        INVOKESPECIAL   java/lang/StringBuilder. <init> (Ljava/lang/String;)V
        ALOAD   2
        INVOKEVIRTUAL   java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
        INVOKEVIRTUAL   java/lang/StringBuilder.toString()Ljava/lang/String;
        ASTORE   3
======================================================================
先构造一个StringBuilder对象(这是在1.5以及之后版本的jdk上解释后的字节码,jdk1.4构造的是StringBuffer对象),然后通过引用str1取出对应的值“a”为字符串类型,作为参数来构造这个StringBuilder,接着调用StringBuilder的append方法,以引用str2对应的值“b”为参数来追加字符串,最后调用它的toString转化为String类型保存。(jvm的指令我不是很懂,说得不妥当或者有欠缺的地方请一定指出来,谢谢!)

如果两个字符串变量相加的操作很频繁,每次操作都要创建一个StringBuilder,并且将它转化为String类型,之后不用的对象又需要GC来回收,会耗费很多的资源。

而如果用以下方法:
======================================================================
StringBuilder   str4   =   new   StringBuilder();
str4.append(str1);
str4.append(str2);
======================================================================
我们先来看看它的字节码:
======================================================================
      L4   (20)
        LINENUMBER   13   L4
        NEW   java/lang/StringBuilder
        DUP
        INVOKESPECIAL   java/lang/StringBuilder. <init> ()V
        ASTORE   4
      L5   (25)
        LINENUMBER   14   L5
        ALOAD   4
        ALOAD   1
        INVOKEVIRTUAL   java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
        POP
      L6   (30)
        LINENUMBER   15   L6
        ALOAD   4
        ALOAD   2
        INVOKEVIRTUAL   java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
        POP
======================================================================
看起来似乎比上面的那种方法操作更麻烦。但仔细看看,用这第二种方法追加字符串,无论加多少次,都只需要在一开始创建一个StringBuilder对象,而且不用调用toString方法,只有在需要取值的时候,人为地去调用它的toString方法。


现在问题来了:
按这么说的话,   用+和用append的区别也只有在对单个string进行不断的追加的时候才会很明显吧。
如果每次的追加操作都是对不同的string呢?是不是两者几乎没有区别?

而我又做了以下试验:

public   class   Test   {
public   static   void   main(String[]   args)
{
String[]   strArray1   =   new   String[500000];
String[]   strArray2   =   new   String[500000];