我对该intern()
方法的有用性有些困惑。
这行代码可以消除我的困惑:
String a = new String("abc").intern();
上面这行代码会创建多少个对象?如果它将在堆内存和字符串池内存中创建一个对象,那么该intern()
方法如何提高性能?
我对该intern()
方法的有用性有些困惑。
这行代码可以消除我的困惑:
String a = new String("abc").intern();
上面这行代码会创建多少个对象?如果它将在堆内存和字符串池内存中创建一个对象,那么该intern()
方法如何提高性能?
上面这行代码会创建多少个对象?
字符串文字在运行时由一个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
to de-dup 将减少长期内存使用并降低长期 GC 成本。
然而,在最近的 JVM 中,GC 将自动删除String
在几个 GC 周期中存活的对象。由于这仅适用于相对长寿命的对象,因此这是一种更有效的去重方法。并且该过程对应用程序是透明的!
简而言之,在大多数情况下,intern()
在应用程序代码中使用该方法没有优点和明显的缺点。不要管它。
您将有两个字符串:
"abc"
- 字符串文字。它还将“abc”添加到字符串池中(见下文)new String("abc")
- 使用 new 运算符显式创建的“abc”的新副本请注意,调用 intern 时不会发生任何事情,因为"abc"
自从声明字符串文字以来,字符串已经存在于字符串池中。
此外,分配不会创建任何新对象。
方法intern
:
返回字符串对象的规范表示。一个字符串池,最初是空的,由 String 类私下维护。当调用 intern 方法时,如果池中已经包含一个等于该 String 对象的字符串,由 equals(Object) 方法确定,则返回池中的字符串。否则,将此 String 对象添加到池中并返回对该 String 对象的引用。由此可见,对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为真时,s.intern() == t.intern() 才为真。 所有文字字符串和字符串值常量表达式都是 interned。字符串文字在 Java™ 语言规范的第 3.10.5 节中定义。
在这种情况下,对实习生的调用没有任何用处,因此您的表现不会有任何提高。