我用javac命令行检查了编译后的代码,发现每当我使用+操作符连接字符串时,编译后的代码就会被StringBuilder的append()方法所替换。现在我认为使用StringBuilder和字符串连接有相同的性能,因为他们有相似的字节码,是正确的吗?
是的,这是真的!但是当你在循环中连接时,行为就不同了。例如
String str = "Some string";
for (int i = 0; i < 10; i++) {
str += i;
}
new StringBuilder
将在每次循环迭代时构造(初始值为str),并且在每次迭代结束时将与初始字符串(实际上是StringBuilder
,初始值为str
)进行连接。
因此,只有当您在循环中使用字符串连接时,才需要自己创建StringBuilder。
主要区别(以及编译器使用StringBuilder
进行字符串连接的原因)是String
是不可变的,而StringBuilder
不是。
例如,单独使用字符串计算s1 + s2 + s3
将需要复制s1
的字符两次。这可以通过使用StringBuilder
来避免。
JLS明确允许这种优化:
实现可以选择在一步中执行转换和连接,以避免创建和丢弃中间String对象。为了提高重复字符串连接的性能,Java编译器可以使用StringBuffer类或类似的技术来减少通过求值表达式创建的中间字符串对象的数量。