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