如果在堆中执行此代码将会发生什么:
String text = "a" + "b" + "c";
String text = "a" + "a" + "a";
我知道在第一个变体中会创建三个String对象。但在第二个? JVM中是否有优化的东西?
答案 0 :(得分:2)
实际上每个只有1个字符串文字。如上所述JLS Sec 3.10.5:
长字符串文字总是可以分解成更短的部分,并使用字符串连接运算符+(第15.18.1节)写成(可能带括号的)表达式。
因此,unable to resolve symbol instanceOf
和"a" + "b" + "c"
与"a" + "a" + "a"
和"abc"
相同。
此外,这些是常量表达式,如JLS Sec 15.28:
中所述常量表达式是表示基本类型值的表达式或不突然完成的字符串,仅使用以下内容组成:
- String类型的原始类型和文字的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)
...
String类型的常量表达式总是“实例化”,以便使用String.intern方法共享唯一的实例。
答案 1 :(得分:2)
要回答问题,JLS提供了两个信息:
JLS(jls-15.28)声明:
String类型的常量表达式总是“实例化”以便 使用String.intern。
方法共享唯一实例
这意味着您在代码中使用常量表达式,它们将被放入您引用的缓存中。
但String text = "a" + "b" + "c";
是一个常量表达式,还是你想知道的三个常量表达式?
我们在JLS的另一个方面得到了这个问题的答案。
JLS(jls-3.10.5,第4点)确实指出:
由常量表达式计算的字符串(第15.28节)计算在 编译时间,然后将其视为文字。
常量表达的示例:
"The integer " + Long.MAX_VALUE + " is mighty big."
这意味着只要编译时间,上面的表达式就是一个 String
字面值。
在某种程度上,它看起来就像你在示例中所做的那样:
String text = "a" + "b" + "c";
text = "a" + "a" + "a";
因此,String text = "a" + "b" + "c";
创建一个String
,即"abc"
,因为常量表达式"a" + "b" + "c"
被视为单个文字。
text = "a" + "a" + "a";
对于编译器来说也是一个String
字面值是完全相同的。
最后,有了两条说明,你可以在堆中获得两个字符串。