Java String 字符串池

来自姬鸿昌的知识库
跳到导航 跳到搜索
public class StringPoolTest {

    // 测试使用双引号创建字符串
    public static void testStringLiteral() {
        String str1 = "testLiteral";
        System.out.println("方法内 str1 的引用: " + System.identityHashCode(str1));
    }

    // 测试使用 new 关键字创建字符串
    public static void testNewString() {
        String str2 = new String("testNew");
        System.out.println("方法内 str2 的引用: " + System.identityHashCode(str2));
    }

    // 测试使用 intern() 方法
    public static void testIntern() {
        String str3 = new String("testIntern").intern();
        System.out.println("方法内 str3 的引用: " + System.identityHashCode(str3));
    }

    public static void main(String[] args) {
        // 测试双引号创建字符串
        testStringLiteral();
        String sameLiteral = "testLiteral";
        System.out.println("方法外 sameLiteral 的引用: " + System.identityHashCode(sameLiteral));

        // 测试 new 关键字创建字符串
        testNewString();
        String newStr = new String("testNew");
        System.out.println("方法外 newStr 的引用: " + System.identityHashCode(newStr));

        // 测试 intern() 方法
        testIntern();
        String internStr = "testIntern";
        System.out.println("方法外 internStr 的引用: " + System.identityHashCode(internStr));
    }
}

System.identityHashCode 是 Java 里 System 类的一个静态方法,其主要用途是返回对象的哈希码,这个哈希码基于对象的内存地址来生成。

  • 基于内存地址:System.identityHashCode 返回的哈希码是依据对象在内存中的实际地址计算得出的。这意味着即使两个对象的内容相同,但只要它们是不同的实例(即内存地址不同),那么它们的 System.identityHashCode 返回值就会不同。
  • 忽略 hashCode 方法重写:通常情况下,Java 中的对象可以重写 hashCode 方法,以根据对象的内容来生成哈希码。不过,System.identityHashCode 不会受对象 hashCode 方法重写的影响,它总是返回基于对象内存地址的哈希码。

当使用双引号直接创建字符串时,例如 String str = "hello";,该字符串会被添加到字符串池中。即使方法调用结束,这个字符串实例依然会留在字符串池中,不会被垃圾回收,因为字符串池里的字符串是全局共享的,会被 JVM 长期保留。

字符串池里字面量在JVM退出之后才会回收。