我有一个不符合屏幕宽度的长字符串。例如。
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个新字符串,这可能会导致性能下降。是这样的吗?或者编译器是否足够智能,以确定我需要的只是一个字符串?我怎么能避免这样做?
答案 0 :(得分:39)
我意识到第二种方式是使用字符串连接,并且会在内存中创建5个新字符串,这可能会导致性能下降。
不,不会。由于这些是字符串文字,因此将在编译时对它们进行评估,并且将仅创建一个字符串。这在Java Language Specification #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
}
答案 1 :(得分:8)
在Java中连接字符串是否总是导致在内存中创建新字符串?
不,它并不总是这样。
如果连接是一个编译时常量表达式,那么它由编译器执行,并将生成的String添加到已编译的类常量池中。在运行时,表达式的值是与常量池条目对应的实习String
。
这将在你问题的例子中发生。
答案 2 :(得分: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
longString == longStringother:true
第一个案例:两个字符串相等(内容相同)
第二种情况:显示连接后只有一个字符串。 因此只创建了一个字符串。