​Java中String的到底存在哪里???

​Java中String的到底存在哪里???

一、堆与字符串常量池

堆是 Java 虚拟机中存储对象实例和数组的内存区域。

字符串常量池(String Pool)是 JVM 专门为字符串字面量分配的区域,用于存放所有用双引号声明的字符串常量,以及运行时调用 intern() 方法生成的字符串。常量池中的相同内容只保存一份,多个引用会指向同一个对象,从而节省内存并提升效率。

字符串池能够成立的前提是 String 对象不可变,这样多个引用共享同一对象才不会互相影响;若可变,则一个引用修改会影响所有引用,显然不可行。

二、Java 创建字符串对象的两种方式

字面值方式

1String str1 = "aaa";2String str2 = "aaa";3System.out.println(str1 == str2); // true

字面量创建时,JVM 会先查常量池:不存在则创建,存在则直接返回引用。str1 和 str2 指向同一个常量池对象,因此 == 为 true。

new 关键字方式

1String str1 = new String("aaa");2String str2 = new String("aaa");3System.out.println(str1 == str2); // false

new String("aaa") 时,若常量池无 "aaa" 会先创建,然后无论是否存在,都会在堆中新建一个 "aaa" 对象并返回其引用。每次 new 都会产生新的堆对象,因此 == 为 false。

三、经典面试题:创建了几个对象?

String s1 = "11"; → 1 个(常量池)。

String s1 = "1" + "1"; → 编译期优化成 "11",1 个(常量池)。

String s1 = new String("11"); → 常量池 1 个 + 堆 1 个 = 2 个。

String s1 = new String("1") + new String("1"); → 常量池 "1" 1 个 + 堆 "1" 2 个 + 堆 "11" 1 个 = 4 个。

四、String.intern() 的作用

常量池已存在:返回常量池中已有的引用,不加入当前对象。

1String a = "abc";2String b = new String("abc");3System.out.println(b.intern() == a); // true

常量池不存在:将当前字符串引用放入常量池,并返回该引用。

1String s1 = new String("x") + new String("y");2System.out.println(s1.intern() == s1); // true

这里 "xy" 不在常量池中,intern() 将 s1 放入池中并返回自身引用。

相关推荐

雷德王在哪个奥特曼第几集
阳台种葱总是死的原因?为什么阳台种葱总是死
国际上比较认可的邮箱有哪些?2025排行前五的国际邮箱