一些字符串追加的问题(+操作符和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];