使用“+”运算符进行字符串连接后创建了多少个对象?

3

我想问在Java中执行以下语句后会创建多少个对象。

String str = "a"+"b"+"c"+"d"

在我看来,只应该创建一个StringBuilder对象。请纠正我并解释其背后的逻辑..提前致谢。

4
您正在创建一个类型为 String 的单个对象。您的代码行中没有 StringBuilder... - deHaar
我了解到这段代码会在内部被更改,类似于new StringBuilder().append("a").append("b").append("c").append("d")...所以我认为答案应该是1。 - Abhishek Jain
如果字符串引用的赋值是“文字”字符串,对象将不会被创建,因为所有的字符串都将在字符串池中。 - The Scientific Method
@TheScientificMethod 谢谢,我不知道这个,只是评论了代码,而不是内部细节... - deHaar
1个回答

10
简单的回答是零个对象。这是一个编译时常量表达式,字节码编译器在创建“.class”文件之前会将其评估为"abcd"
事实上,对于现代JVMs,与文字和编译时常量表达式相关联的String对象的实例化是惰性的,因此第一次执行该语句时可能只创建一个单独的String对象。但仅限于第一次。
因此,更正确的答案是零个或一个String对象,具体取决于:
- 字符串字面值共享的JVM实现(惰性或饱和),以及 - 是否是使用"abcd"文字或编译时常量的任何语句的第一次执行。
然后,如果永远不访问str,则该语句可能会被JIT编译器优化掉。
如果考虑到类卸载的可能性,情况就会变得更加复杂。

1
如果对 "abcd" 进行评估,编译器不会将其转换为对象吗? - Abhishek Jain
1
那么问题的确切答案是0或1,对吧? - Maxim
1
@Maxim - 严格来说,答案是“零或者,或者零或一,取决于Java版本”。这取决于JVM用于实例化字面字符串对象的策略。 - Stephen C
@Maxim - 实际上,当与字面值对应的String对象被添加到字符串池中时,将会有额外的引用与代码中“提及”它的类或类相关联。这些引用将防止String对象从池中被清除...除非类本身被垃圾回收。而这只有在进行动态类加载时才会发生。 - Stephen C
另一个方面,当你禁用解释器时,即时编译器可能会消除整个语句,因为没有实际使用 str,甚至在第一次执行之前,所以不会创建任何字符串。此外,如果另一个代码之前使用了字面量 "abcd",则该语句不会创建字符串,因为它将重用池中的实例。 - Holger
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接