TL;DR:如果你真的需要这样做new String("abc")
,你就会知道你需要这样做,并且你会知道为什么。它是如此罕见,以至于说你永远不需要这样做几乎是有效的。只需使用"abc"
.
长版:
当您拥有代码new String("abc")
时,会在不同时间发生以下事情:
- 加载包含该代码的类时,如果带有字符的字符串
"abc"
不在实习池中,则会创建并放入实习池。
new String("abc")
代码运行时
:
- 来自实习生池的字符串的引用
"abc"
被传递到String
构造函数中。
- 通过将传入的字符复制到构造函数中来创建和初始化一个新对象。
String
String
- 新
String
对象将返回给您。
如果使用 new 创建的字符串“abc”也将字符串放入池中,那么为什么intern()
说如果字符串池包含字符串,则返回池中的字符串,否则将字符串对象添加到池中。
因为这就是这样intern
做的。请注意,调用intern
字符串文字是无操作的;字符串文字都是自动实习的。例如:
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = s1.intern(); // No-op
System.out.println(s1 == s2); // "true"
System.out.println(s1 == "abc"); // "true", all literals are interned automatically
另外我想知道我们是否使用 new 创建了一个字符串,那么实际上创建了多少个对象?
您创建至少一个String
对象(新的、非实习的),可能还有两个(如果字面量尚未在池中;但同样,当类文件的字面量被加载时,该位更早发生):
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = new String(s1); // Create a new `String` object (guaranteed)
System.out.println(s1 == s2); // "false"
String s3 = s2.intern(); // Get the interned version of the string with these characters
System.out.println(s1 == s3); // "true"