在Java中连接字符串是否总会导致在内存中创建新字符串?

Cod*_*lue 24 java compiler-construction string string-concatenation

我有一个不符合屏幕宽度的长字符串.例如.

String longString = "This string is very long. It does not fit the width of the screen. So you have to scroll horizontally to read the whole string. This is very inconvenient indeed.";
Run Code Online (Sandbox Code Playgroud)

为了便于阅读,我想到了这样写 -

String longString = "This string is very long." + 
                    "It does not fit the width of the screen." +
                    "So you have to scroll horizontally" +
                    "to read the whole string." +
                    "This is very inconvenient indeed.";
Run Code Online (Sandbox Code Playgroud)

但是,我意识到第二种方式使用字符串连接,并将在内存中创建5个新字符串,这可能会导致性能下降.是这样的吗?或者编译器是否足够智能,以确定我需要的只是一个字符串?我怎么能避免这样做?

ass*_*ias 44

我意识到第二种方式使用字符串连接,并将在内存中创建5个新字符串,这可能会导致性能下降.

不,不会.由于这些是字符串文字,因此将在编译时对它们进行评估,并且创建一个字符串.这在Java语言规范#3.10.5中定义:

长字符串文字总是可以分解为较短的部分,并使用字符串连接运算符+
[...] 写成(可能带括号的)表达式.
此外,字符串文字始终引用类String的相同实例.

  • 由常量表达式计算的字符串(第15.28节)在编译时计算,然后将其视为文字.
  • 在运行时通过串联计算的字符串是新创建的,因此是不同的.

测试:

public static void main(String[] args) throws Exception {
    String longString = "This string is very long.";
    String other = "This string" + " is " + "very long.";

    System.out.println(longString == other); //prints true
}
Run Code Online (Sandbox Code Playgroud)

但是,下面的情况是不同的,因为它使用一个变量 - 现在有一个连接,并创建了几个字符串:

public static void main(String[] args) throws Exception {
    String longString = "This string is very long.";
    String is = " is ";
    String other = "This string" + is + "very long.";

    System.out.println(longString == other); //prints false
}
Run Code Online (Sandbox Code Playgroud)

  • @CodeBlue仅汇集字符串文字.在运行时创建的字符串不是.除非你强制它们使用`intern()`方法进入池中.例如,在第二个代码片段中,您可以尝试使用`String other =("This string"+ is +"very long.").intern();`来查看差异. (2认同)
  • 值得注意的是,如果我们在第二个示例中将 `final` 修饰符添加到 `is` 中,则 `" is "` 将被视为文字,因此在输出中生成 `true`。 (2认同)

Ste*_*n C 8

在Java中连接字符串是否总会导致在内存中创建新字符串?

不,它并不总是这样.

如果连接是编译时常量表达式,那么它由编译器执行,并且生成的String被添加到已编译的类常量池中.在运行时,表达式的值是String与常量池条目对应的interned .

这将在您的问题中的示例中发生.