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)
在Java中连接字符串是否总会导致在内存中创建新字符串?
不,它并不总是这样.
如果连接是编译时常量表达式,那么它由编译器执行,并且生成的String被添加到已编译的类常量池中.在运行时,表达式的值是String
与常量池条目对应的interned .
这将在您的问题中的示例中发生.