java字符串intern()方法使字符串对象进入常量池并返回池中引用,字面量自动入池,new创建在堆,==比较引用,equals比较内容,从java 7起常量池位于堆内存。

Java 字符串的 intern() 方法常被用来考察对字符串常量池、对象创建机制和内存模型的理解。解这类题,核心是抓住两点:字符串字面量自动入池、intern() 的执行逻辑(首次调用时将字符串对象放入常量池并返回池中引用,已存在则直接返回池中引用),以及 == 比较的是引用而非内容。
搞清字符串常量池的位置和触发时机
从 Java 7 开始,字符串常量池被移到堆内存中(不再是永久代),但行为逻辑没变:所有双引号声明的字符串字面量(如 "abc")在类加载时就进入常量池;通过 new String("abc") 创建的字符串对象默认在堆上,不自动入池。
- 字面量直接赋值:
String s1 = "abc";→s1指向常量池中的对象 - new 创建:
String s2 = new String("abc");→s2指向堆中新对象,常量池里已有"abc"(来自字面量或之前操作) -
intern()是手动“申请入池”:若池中已有相同内容字符串,返回池中引用;否则把当前字符串对象(或其副本)加入池,并返回该引用
掌握 == 和 equals 的区别在 intern 场景下的表现
== 判断是否为同一对象(地址相同),equals() 判断内容是否相等。而 intern() 的作用就是让不同来源的字符串“指向同一个常量池入口”,从而让 == 成立。
-
new String("hello").intern() == "hello"→ true(因为"hello"字面量已在池中,intern()返回池中引用) -
new String("world").intern() == new String("world").intern()→ true(两次都返回池中唯一引用) -
new String("java") == new String("java")→ false(两个堆上不同对象)
注意 intern 的返回值永远是常量池中的引用
即使原字符串是堆上新建的,调用 intern() 后返回的也不是原对象,而是池中那个——所以不能靠它“修改原对象”,也不能误以为 intern() 会改变原变量指向(除非重新赋值)。
-
String s = new String("test");→s指向堆对象 -
s.intern();→ 返回常量池中"test"的引用,但s还是指向堆对象 -
s = s.intern();→ 这才让s指向常量池,后续s == "test"才为 true
结合典型代码题快速判断
遇到类似下面的题目,按“字面量先入池 → new 对象在堆 → intern 查池、返池引用 → == 看是否同址”四步推演:
-
String a = "ab"; String b = "ab"; System.out.println(a == b);→ true(都是字面量,共用池中对象) -
String c = new String("cd"); String d = "cd"; System.out.println(c == d);→ false(c 在堆,d 在池) -
System.out.println(c.intern() == d);→ true(c.intern()返回池中"cd"引用,与d相同)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











