14

我有一个巨大的字符串如下:

String str = "aaaaaaa" 
        + "bbbbbbbb" 
        + "cccccccc" 
    .... 

        + "zzzzzzzz";  // about 200 lines long

是不是很浪费内存?将它放在一条线上或使用它会更好StringBuilder吗?这样做是为了创建一个长 sql。

4

5 回答 5

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"分开。高效版本等价于O:

int value = ...;
String x = "a" + value + "bc";

我不记得曾经将其用作合法的微优化,但这至少是一个兴趣点。

于 2013-04-25T16:19:05.373 回答
4

在当前版本的 Java 中,每个+(连接)操作都会自动编译为一个操作。但是,如果它在一个循环内,它将为每次迭代创建一个新的,否定它的效果 - 所以你会更好地管理显式。StringBuilder append()StringBuilderStringBuilder

于 2013-04-25T16:18:50.670 回答
2

不,编译器会为你优化成StringBuilder.

编辑:正如 Louis Wasserman 指出的那样,它还会为您组合字符串文字,因此上面的语句在编译时只是一个字符串。

于 2013-04-25T16:17:14.997 回答
1

AFAIK JVM 内部有一个字符串池,您创建的每个字符串都存储在那里,丢弃最旧/最少使用的字符串(我不确定它如何选择哪些字符串)。如果你明确地调用 String.intern() 你是在告诉 JVM 将字符串放入池中。

当您使用 + 连接两个字符串时,您最终会在池中得到三个字符串。如果你连接 a + b + c,你最终会得到 5 个字符串 (a, b, ab, c, abc)

至少那是我对旧 JVM 版本的回忆,但 Luiggi 很可能是对的,在较新的版本上它的内部优化

于 2013-04-25T16:25:27.853 回答
1

编码:

String str = "aaaaaaa" + "bbbbbbbb" + "cccccccc";

在编译时转换为:

String str = (new StringBuilder()).append("aaaaaaa").append("bbbbbbbb").append("cccccccc").toString();

因此,使用 StringBuilder 似乎没有任何区别。

有一篇非常好的文章将 concat (+) 与 StringBuilder 和 StringBuffer 的性能进行了密切比较,并附有折线图:

StringBuilder vs StringBuffer vs String.concat - 做对了

于 2013-04-25T16:33:16.890 回答