new string("abc")创建1个或2个对象:若常量池中不存在"abc",则先在常量池创建该字符串对象,再在堆中新建string对象,共2个;若常量池中已存在,则仅在堆中创建1个对象。

这道题考的不是死记数字,而是对 JVM 字符串机制的理解深度。面试官真正想看的是:你能不能把常量池、堆内存、编译期优化、intern 机制这几块串起来讲清楚,而不是背“1个或2个”这种模糊答案。
核心考点一:常量池是否存在决定对象数量
关键不在代码本身,而在执行前常量池的状态:
- 如果
"abc"是第一次出现(比如整个类里没其他地方用过它),new String("abc")会先在字符串常量池中创建一个"abc"对象,再在堆上 new 出一个新 String 实例 → 共 2 个对象 - 如果之前已有
String s = "abc";或其他字面量使用过"abc",常量池里已存在,那这次只在堆上 new 一个 → 共 1 个对象
核心考点二:字节码层面验证逻辑
面试官可能让你现场分析字节码,重点看 ldc 和 new 指令:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
ldc "abc"表示从常量池加载引用,说明该字符串已在池中(或即将被放入) -
new java/lang/String明确表示堆上分配新对象 - 若同一字符串反复出现,
ldc指令指向的是同一个常量池索引,证明复用
核心考点三:混淆项设计(常见变形题)
真题往往加干扰,比如:
-
new String("a") + new String("b")→ 至少 4 个对象(常量池 "a"、"b";堆上两个 new;拼接后 StringBuilder.toString() 新建的堆对象) -
"ab" + "cd"→ 编译期优化为"abcd",常量池中最多 1 个对象(0 或 1) -
String s = "ab"; s += "cd";→ 运行期拼接,StringBuilder + toString,生成新堆对象,不进常量池
核心考点四:intern() 的作用与陷阱
这是区分理解深度的关键点:
-
new String("abc").intern():若常量池无 "abc",则把堆中对象引用存入池并返回;若有,则直接返回池中引用 -
==比较时,new String("abc").intern() == "abc"一定为 true,但new String("abc") == "abc"一定为 false - JDK7+ 后 intern() 存的是堆对象引用,不是复制字符串内容,这点常被误读
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










