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

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

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个新字符串,这可能会导致性能下降。 是这样的吗? 或者编译器是否足够智能以确定我需要的只是一个字符串? 我怎么能避免这样做?

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

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

不,它并不总是这样。

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

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

请根据您的输入检查以下代码段:

 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
longString == longStringother:true

第一种情况 :两个字符串相等(内容相同)

第二种情况 :显示连接后只有一个字符串。 因此只创建一个String。