这两行之间有什么区别?
stringBuilder.append("Text " + counter + " more text");
stringBuilder.append("Text ").append(counter).append(" more text");
假设计数器是一个递增的int,第一行是否在每次调用时都创建一个字符串"Text 0 more text"
,"Text 1 more text"
等,而第二行只创建这两个字符串一次:{{ 1}}和"Text "
?这是对的吗?
答案 0 :(得分:15)
简而言之,是的,除了每次都重复使用"Text "
和" more text"
的相同字符串文字。
第二种变体更有效,因为它将三个组件中的每一个直接写入StringBuilder
。
相反,第一个变体创建另一个 - 未命名 - StringBuilder
,将三个组件写入其中,调用其toString()
方法并将结果写入命名的stringBuilder
。
总之,第一个变体创建了一个额外的StringBuilder
对象和一个额外的String
对象,并且比第二个变体复制了两倍的字符串数据。
答案 1 :(得分:3)
是的(大部分)是正确的。
实际上,第二个根本不会创建新的字符串,因为它每次都重用相同的字符串。它将使用“文本”和“更多文本”字符串的实际版本。
第一个将使用编译器生成的StringBuilder为“Text 1 more text”和“Text 2 more text”创建一个字符串。
答案 2 :(得分:1)
是的,你的解释是(几乎)正确。
第一行始终创建String
对象,如"Text 0 more text"
,而第二行不创建此类String
对象。
第二行不创建 *所有String
的任何* "Text "
个对象和" more text"
String
个文字每次执行该行时都不会重新创建。它们只创建一次。
然而,stringBuilder
对{{1}}的影响完全相同。
答案 3 :(得分:1)
几乎是正确的。
我会说更多。由于java字符串缓存所有硬编码字符串,因此不会在每次迭代时创建字符串“Text”和“more text”的实例。
答案 4 :(得分:1)
这取决于Java是否实际上是字符串,但它仍然效率低下。
字符串是不可变的,所以,如果你使用.append(“String”+ something +“String”),你强制Java创建一堆新的字符串,这样它最终可以用最终的字符串添加到缓冲区。这是一个经常被遗忘的内存耗尽,我已经看到通过消除这种类型的代码在Web应用程序中显着改进了内存使用。