不,不完全是。
首先,语义略有不同。如果a 是null,则a.concat(b) 会抛出NullPointerException,但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 数组(根据需要调整大小),然后在创建最终的 String 时将其丢弃。在实践中,内存分配速度惊人。
更新: 正如 Pawel Adamski 所说,最近的 HotSpot 的性能发生了变化。 javac 仍然产生完全相同的代码,但字节码编译器会作弊。简单的测试完全失败,因为整个代码体都被丢弃了。对System.identityHashCode 求和(不是String.hashCode)表明StringBuffer 代码有一点优势。下一次更新发布或您使用不同的 JVM 时可能会发生变化。来自@lukaseder,a list of HotSpot JVM intrinsics。