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

问题描述 投票:0回答:3

我有一条很长的字符串,不适合屏幕的宽度。例如。

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.";

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

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.";

但是,我意识到第二种方法使用字符串连接,会在内存中创建 5 个新字符串,这可能会导致性能下降。是这样吗?或者编译器是否足够聪明,能够弄清楚我所需要的实际上只是一个字符串?我怎样才能避免这样做呢?

java string string-concatenation
3个回答
45
投票

我意识到第二种方法使用字符串连接,并将在内存中创建 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 }

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

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 }



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

不,它并不总是这样做。

如果连接是编译时常量表达式,则由编译器执行,并将生成的 String 添加到编译后的类常量池中。 在运行时,表达式的值是对应于常量池条目的 interned

String


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


1
投票

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."; String longStringOther = "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."; System.out.println(" longString.equals(longStringOther) :"+ longString.equals(longStringOther)); System.out.println(" longString == longStringother : " + (longString == longStringOther ));

输出:

longString.equals(longStringOther) :true

长字符串==长字符串其他:true


第一种情况

:两个字符串相等(具有相同的内容)

第二种情况

:表明连接后只有一个字符串。 因此只创建了一个字符串。

© www.soinside.com 2019 - 2024. All rights reserved.