String.intern() 在 Java 中是一个非常有用的方法,它关联到字符串池(String Pool)的概念。字符串池是 JVM 中用于存储一组唯一的字符串字面量的特殊存储区域。这个设计主要是为了减少因为多个字符串对象而导致的内存浪费。当你调用一个字符串对象的 intern() 方法时,JVM 会检查字符串池中是否已经存在一个等价的字符串(即,内容相同的字符串)。如果已经存在,那么 intern() 方法会返回那个已经存在的字符串的引用;如果不存在,当前字符串将会被添加到池中,并返回这个字符串的引用。

基本操作
调用 intern() 方法会检查池中是否已经存在一个等价的字符串。
如果存在,返回池中的字符串引用;如果不存在,将此字符串添加到池中并返回其引用。
示例

String s1 = new String("hello");
String s2 = "hello";
String s3 = s1.intern();

// 此时,s1 != s2 为 true,因为 s1 指向堆中的对象,而 s2 指向字符串池中的对象。
// 但是,s2 == s3 为 true,因为 s3.intern() 返回了字符串池中的 "hello" 引用。


System.out.println(s1 == s2); // 输出 false
System.out.println(s2 == s3); // 输出 true

为什么使用 String.intern()?

内存效率:通过确保内容相同的所有字符串共享相同的内存位置,能够节省内存消耗。
提高性能:对于已经被 intern 的字符串,用 == 来比较引用会比用 equals 方法比较内容更快。

考虑因素和缺点
永久代(PermGen)/ 元空间(Metaspace)存储:在 Java 7 之前,interned 字符串存储在 PermGen 空间,Java 7 之后存储在主堆内存中。这意味着,如果滥用 intern,可能会影响到内存的使用。
interning 的性能成本:interning 过程会有自己的 CPU 成本。如果 intern 大量唯一字符串,这个过程可能是昂贵的。
用例特定:在某些情况下,比如处理大量重复字符串对象时,interning 字符串能显著节省内存和提高性能。但是,如果大多数字符串都是唯一的,或者内存和性能不是主要考虑因素,那么使用它的好处可能不会超过开销。

总之,合理使用 String.intern(),了解你的应用需求和对性能及内存使用的潜在影响,是提高 Java 应用效率的一个方式。


edagarli
4.3k 声望91 粉丝

github: