不,不是。
首先,语义上略有不同。如果a
是null
,则a.concat(b)
抛出一个NullPointerException
,但a+=b
将把原来的值a
就好像它是null
。此外,该concat()
方法仅接受String
值,而+
操作员会将参数无提示地转换为String(使用toString()
对象的方法)。因此,该concat()
方法在接受方面更加严格。
要深入了解,请写一个简单的类 a += b;
public class Concat {
String cat(String a, String b) {
a += b;
return a;
}
}
现在与一起拆卸javap -c
(包括在Sun JDK中)。您应该会看到一个列表,其中包括:
java.lang.String cat(java.lang.String, java.lang.String);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/ String;
18: astore_1
19: aload_1
20: areturn
所以,a += b
相当于
a = new StringBuilder()
.append(a)
.append(b)
.toString();
该concat
方法应该更快。但是,使用更多的字符串StringBuilder
,至少在性能方面,该方法是成功的。
String
and 的源代码StringBuilder
(及其包专用基类)在Sun JDK的src.zip中可用。您会看到正在建立一个char数组(根据需要调整大小),然后在创建final时将其丢弃String
。实际上,内存分配出奇的快。
更新:正如Pawel Adamski指出的那样,在最近的HotSpot中,性能已经发生了变化。javac
仍然产生完全相同的代码,但是字节码编译器作弊。简单的测试完全失败,因为整个代码主体都被丢弃了。总结System.identityHashCode
(不是String.hashCode
)表明StringBuffer
代码有一点优势。在发布下一个更新时,或者使用其他JVM时,可能会发生更改。从@lukaseder,热点JVM内部函数列表。