【发布时间】:2013-03-07 10:51:49
【问题描述】:
我使用 javac 命令行查看了我的编译代码,我看到每当我使用带有 + 运算符的字符串连接时,编译代码都会被 StringBuilder 的 append() 方法替换。 现在我认为使用 StringBuilder 和 String 连接具有相同的性能,因为它们具有相似的字节码,是否正确?
【问题讨论】:
标签: java string jvm stringbuilder javap
我使用 javac 命令行查看了我的编译代码,我看到每当我使用带有 + 运算符的字符串连接时,编译代码都会被 StringBuilder 的 append() 方法替换。 现在我认为使用 StringBuilder 和 String 连接具有相同的性能,因为它们具有相似的字节码,是否正确?
【问题讨论】:
标签: java string jvm stringbuilder javap
是的,这是真的!但是当您在循环中连接时,行为会有所不同。例如
String str = "Some string";
for (int i = 0; i < 10; i++) {
str += i;
}
新的StringBuilder 将在每次循环迭代时构造(初始值为str),并且在每次迭代结束时将与初始字符串连接(实际上是StringBuilder,初始值为str)。
因此,只有在循环中使用字符串连接时,您才需要自己创建 StringBuilder。
【讨论】:
主要区别(以及编译器使用StringBuilder 进行字符串连接的原因)是String 是不可变的,而StringBuilder 不是。
例如,单独使用字符串计算s1 + s2 + s3 需要将s1 的字符复制两次。使用StringBuilder 可以(并且已经)避免这种情况。
JLS 明确允许此优化:
实现可以选择在一个步骤中执行转换和连接,以避免创建然后丢弃中间 String 对象。为了提高重复字符串连接的性能,Java 编译器可以使用 StringBuffer 类或类似技术来减少通过计算表达式创建的中间 String 对象的数量。
【讨论】: