不,不完全是。
首先,语义上略有不同。如果a
是null
,则a.concat(b)
抛出 aNullPointerException
但a+=b
会将 的原始值a
视为null
。此外,该concat()
方法仅接受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
和StringBuilder
(及其包私有基类)的源代码可在 Sun JDK 的 src.zip 中找到。您可以看到您正在构建一个 char 数组(根据需要调整大小),然后在创建 final 时将其丢弃String
。在实践中,内存分配速度惊人。
更新:正如 Pawel Adamski 所说,最近的 HotSpot 的性能发生了变化。javac
仍然产生完全相同的代码,但字节码编译器作弊。简单的测试完全失败,因为整个代码体都被丢弃了。Summing System.identityHashCode
(not String.hashCode
) 显示StringBuffer
代码有一点优势。下一次更新发布或您使用不同的 JVM 时可能会发生变化。来自@lukaseder,HotSpot JVM 内在函数列表。