String 类 intern() 方法作用看这一篇就够了

41 阅读4分钟

String 类中的 intern() 方法用于返回字符串池中与当前字符串内容相同的字符串对象。它的主要作用是优化内存使用,确保相同内容的字符串只会存储一次,从而提高内存效率和性能。

详细解释

在 Java 中,字符串常量池(也称为字符串池或字面量池)是一个专门存储字符串常量的内存区域。当你创建一个字符串常量(如 String str = "hello";)时,Java 会首先检查字符串池中是否已经存在该字符串。如果存在,它会直接返回池中的字符串引用;如果不存在,它会将该字符串加入池中。

intern() 方法的作用是将字符串添加到这个池中,或者如果池中已经存在具有相同内容的字符串,返回池中的那个字符串引用。

intern() 方法的工作机制

  1. 查找字符串池: 当调用 intern() 方法时,Java 会检查常量池中是否已存在一个与当前字符串内容相同的字符串。

  2. 返回池中的引用

    • 如果池中已经有一个相同的字符串,intern() 方法会返回该字符串在池中的引用。
    • 如果池中没有相同的字符串,intern() 会将当前字符串添加到池中,并返回该新加入字符串的引用。

使用示例

public class StringInternExample {
    public static void main(String[] args) {
        // 创建一个字符串对象
        String str1 = new String("hello");

        // 使用 intern() 方法
        String str2 = str1.intern();
        
        // 直接通过字面量创建字符串
        String str3 = "hello";

        System.out.println(str1 == str2); // 输出: false
        System.out.println(str2 == str3); // 输出: true
    }
}
  • 解释

    • str1 是通过 new 创建的字符串,它指向堆内存中的一个字符串对象。
    • str2 = str1.intern() 会返回字符串池中 "hello" 的引用,假设 "hello" 已经在池中。
    • str3 是通过字面量 "hello" 创建的字符串,它直接指向字符串池中的 "hello"

    输出:

    • str1 == str2 输出 false,因为 str1 指向堆中的对象,而 str2 指向字符串池中的对象。
    • str2 == str3 输出 true,因为 str2str3 都指向字符串池中的 "hello"

何时使用 intern()

intern() 方法常用于以下场景:

  1. 内存优化:当你有大量的字符串,而且这些字符串内容相同时,使用 intern() 可以确保这些相同的字符串内容只存储一次,从而节省内存。通过将字符串常量存储在字符串池中,可以避免重复存储相同内容的字符串。

  2. 性能优化:由于字符串池中的字符串是唯一的,使用 intern() 可以通过引用比较(==)来代替内容比较(equals()),提高性能。例如,在大量字符串比较中,如果这些字符串已经被池化,那么比较它们的引用会更高效。

  3. 与数据库的字符串处理:在处理大量来自外部系统(如数据库)的字符串数据时,使用 intern() 可以减少内存占用,尤其是当这些数据集中的重复字符串较多时。

注意事项

  • 性能开销intern() 可能会有性能开销,因为它需要检查字符串池中是否已经有相同的字符串。如果字符串池中没有该字符串,它还会将其添加到池中。对于小规模的应用程序或字符串不重复的场景,过度使用 intern() 可能会降低性能。

  • 垃圾回收问题:字符串池中的字符串不会被垃圾回收(GC)删除,因此如果不谨慎使用 intern(),可能会导致内存泄漏问题,尤其是在字符串池中积累了大量不再使用的字符串时。

总结

intern() 方法用于将字符串添加到字符串常量池中,或者返回池中已经存在的相同内容的字符串引用。它有助于减少内存消耗,并可以提高字符串比较的效率,但也需要谨慎使用,以避免不必要的性能开销和内存泄漏。