下面这两段代码是否相同?
String foo = "foo";
String foo = new String("foo").intern();
new String("foo").intern()
版本实际上会执行这些步骤,生成一个新的字符串对象,然后将其放入字符串池中)。
String#intern
中的两个相关引用:intern
方法时,如果池已经包含与该 String
对象相等的字符串(由 equals(Object)
方法确定),则返回池中的字符串。否则,将该 String
对象添加到池中,并返回对该 String
对象的引用。因此,对于任意两个字符串s和t,如果且仅当
s.equals(t)
为true
时,s.intern() == t.intern()
是真的。
所以我认为答案是肯定的,尽管第二种方法将不得不在池中搜索。
编辑
如T.J. Crowder所建议
当调用intern方法时,如果池中已经包含一个等于该String对象的字符串(根据equals(Object)方法确定),则返回池中的字符串。否则,将该String对象添加到池中,并返回对该String对象的引用。
所有文字字符串和值为字符串的常量表达式都被国际化。
intern
方法时,如果池中已经包含一个与此String
对象相等的字符串(由equals(Object)
方法确定),则从池中返回该字符串。否则,将该String
对象添加到池中,并返回对该String
对象的引用。"* 和 "所有文字字符串和字符串值常量表达式都会进行内部化。" - T.J. Crowder第一个,即
String foo = "foo";
String foo = new String("foo").intern();
在这里,我们使用new String()创建一个字符串,然后手动保存到字符串常量池中。如果我们没有使用intern(),它就不会保存在字符串常量池中。
为了更好的理解,请参考此链接 -
http://javacodingtutorial.blogspot.com/2013/12/comparing-string-objects-intern-other.html
intern()
就不会在字符串池中有String显然是错误的,因为它仍然使用字面量"foo"
。在这种情况下,intern
的效果是,对String构造函数的调用不再重要,而foo
指的是字面版本"foo"
而不是新构造的版本。 - Tom是的,它们是相同的。基本上,intern()
返回一个在 VM 中唯一的字符串表示形式。这意味着您可以使用==
而不是.equals()
来比较字符串,从而节省性能。
new String("foo").intern()
,一旦注意到调用构造函数没有副作用。或者不会消除,因为除非它在一个紧密循环内,否则它不符合值得优化的门槛。 - T.J. Crowderintern
,即使字符串内容不同,你也知道字符串引用是唯一的。这样的用例不多,我认为不会有很多人需要,但由于按照定义new String("foo") != "foo"
,在某些情况下可能会派上用场。虽然这样的情况不多,我不认为会有很多。 - T.J. Crowder