我有一个巨大的字符串如下:
String str = "aaaaaaa"
+ "bbbbbbbb"
+ "cccccccc"
....
+ "zzzzzzzz"; // about 200 lines long
这是对记忆的大浪费吗?将它放在一行中还是使用StringBuilder
会更好吗?
这样做是为了创建一个很长的sql。
答案 0 :(得分:25)
没有。如果你的所有字符串都是常量的(就像你的问题一样),编译器将在编译时执行串联 。因此,最终会比StringBuilder
版本执行更好。
否则将使用StringBuilder
(或StringBuffer
)来执行任何非常量部分的连接。
所以编译版本:
String x = "a" + "b";
应与完全相同:
String x = "ab";
请注意,“非常数”部分可能意味着您有时可以明智地使用包围来获得(非常小的)额外效率。例如:
int value = ...;
String x = "a" + value + "b" + "c";
......效率低于:
int value = ...;
String x = "a" + value + ("b" + "c");
...首先分别添加"b"
和"c"
。高效版本等同于:
int value = ...;
String x = "a" + value + "bc";
我不记得永远看到这被用作合法的微优化,但它至少是一个兴趣点。
答案 1 :(得分:4)
在当前版本的Java中,每个+
(串联)操作都会自动编译为StringBuilder
append()
操作。但是,如果它在一个循环中,它将为每次迭代创建一个新的StringBuilder
,否定它的影响 - 所以你最好明确地管理StringBuilder
。
答案 2 :(得分:2)
没有。编译器会将此优化为StringBuilder
。
编辑:正如Louis Wasserman所指出的,它也将为你组合字符串文字,所以上面的语句在编译时只是一个字符串。
答案 3 :(得分:1)
AFAIK JVM内部有一个字符串池,你创建的每个字符串都存储在那里,丢弃最旧/最少使用的字符串(我不确定它是如何选择的)。如果你明确地调用String.intern(),则告诉JVM将String放入池中。
当你使用+连接两个字符串时,你最终会在池中使用三个字符串。 如果你连接a + b + c,你最终会得到5个字符串(a,b,ab,c,abc)
至少这是我在旧JVM版本上的回忆,但是Luiggi很可能是正确的,在内部优化的新版本
答案 4 :(得分:1)
代码:
String str = "aaaaaaa" + "bbbbbbbb" + "cccccccc";
在编译时转换为:
String str = (new StringBuilder()).append("aaaaaaa").append("bbbbbbbb").append("cccccccc").toString();
因此,使用StringBuilder似乎没有任何区别。
有一篇非常好的文章将concat(+)与StringBuilder和StringBuffer的性能进行了比较,并附有折线图: