我对intern()
方法的有用性感到困惑。
这行代码可以消除我的困惑:
String a = new String("abc").intern();
以上代码行将创建多少个对象?如果它将在堆内存以及字符串池内存中创建一个对象,那么intern()
方法如何提高性能?
答案 0 :(得分:2)
以上代码行将创建多少个对象?
字符串文字在运行时由一个String
对象表示。如果尚未创建该对象,则可以通过执行该语句来(懒惰地)创建 。无论哪种情况,代表文字的对象都将被插入。 (此过程中创建的String
对象的数量是取决于Java版本的实现细节。是的,确实如此。)
每次new String(...)
都会创建一个对象。
由于原始String
对象已被阻止,因此intern()
调用将返回该对象;即表示字符串文字的String
:您开始使用的文字。
因此,总而言之,您的代码可能导致直接在幕后最多创建三个对象,但是由new
创建的对象在语句结尾将不可访问。
的确如此,
String a = new String("abc").intern();
和
String a = "abc";
给出相同的结果,new
/ intern
序列完全浪费时间。
如果它将在堆内存以及字符串池内存中创建一个对象,那么intern()方法如何提高性能?
不会直接提高性能:
如果您可以实习数据结构中的所有字符串,则有潜在的间接好处。然后,您可以使用==
而不是equals(Object)
来测试是否相等。
但是,您需要权衡equals
的成本和intern
的成本,因此您需要进行一些对象比较,然后才能获得净性能。另外,如果您忘记插入其中一个字符串,则==
可能会为您提供对equals
的不同答案。 (这可能是一个错误!)
在较早的JVM中,如果您有许多寿命长的String
对象,则有潜在的间接收益。使用intern
进行重复数据删除将减少长期内存使用并减少长期GC成本。
但是,在最近的JVM中,GC将自动 去重复String
个对象,这些对象可以保留几个GC周期。由于此 only 仅适用于寿命相对较长的对象,因此这是一种更有效的重复数据删除方法。而且该过程对应用程序是透明的!
简而言之,在大多数情况下,在应用程序代码中使用intern()
方法没有优点和缺点。别管它。
答案 1 :(得分:1)
您将有两个字符串:
"abc"
-字符串文字。还会在字符串池中添加“ abc”(请参阅下文)new String("abc")
-使用新运算符明确创建的“ abc”新副本请注意,调用intern不会发生任何事情,因为自声明字符串文字以来,字符串池中已经存在字符串"abc"
。
该分配也不会创建任何新对象。
方法intern
:
返回字符串对象的规范表示。 最初为空的字符串池由String类私有维护。调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。因此,对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()== t.intern()为true。 所有文字字符串和字符串值常量表达式均已插入。字符串文字是在Java™语言规范的第3.10.5节中定义的。
在这种情况下,对实习生的调用没有任何用处,因此您的性能不会得到任何提高。