最多创建2个对象:若字符串常量池中不存在"abc",则新建1个常量池对象和1个堆对象;若已存在,则复用常量池对象并新建1个堆对象。

这行代码 String s = new String("abc"); 在 Java 中**最多创建 2 个对象**,具体取决于字符串常量池中是否已存在 "abc"。
1. 字符串字面量 "abc" 会进入字符串常量池(可能不新建)
当编译器看到 "abc" 这个字面量时,会在类加载阶段将其放入字符串常量池。如果池中**之前没有** "abc",就新建一个字符串对象并驻留;如果**已经存在**(比如前面代码中出现过 String a = "abc";),则直接复用,不新建对象。
- 这个对象类型是
java.lang.String,存储在方法区(JDK 7+ 是堆中的字符串常量池) - 它由 JVM 自动管理,不可变,且被所有相同字面量共享
2. new String("abc") 一定会在堆中新建一个对象
无论常量池中有没有 "abc",new String(...) 都会调用构造方法,在堆内存中**显式创建一个新的 String 对象**。这个对象内容与常量池中的 "abc" 相同,但它是独立的、不同的对象(== 比较为 false)。
- 该对象内部的
value字段(char[] 或 byte[])通常会引用常量池中对应字符串的底层数组(JDK 7+ 优化),但 String 实例本身是新分配的 - 所以这里必然产生 1 个堆对象
3. 总结:对象数量分两种情况
情况一(首次出现 "abc"):常量池中无 "abc" → 创建 1 个常量池对象 + 1 个堆对象 = 共 2 个对象
立即学习“Java免费学习笔记(深入)”;
情况二(之前已有 "abc"):常量池中已有 "abc" → 复用常量池对象 + 新建 1 个堆对象 = 共 1 个新对象(总计新增 1 个)
4. 验证小技巧(可选)
可以用 == 和 .equals() 辅助理解:
String s1 = "abc"; String s2 = new String("abc"); System.out.println(s1 == s2); // falseSystem.out.println(s1.equals(s2)); // true
也可以用 String.intern() 强制将堆中字符串“登记”进常量池,帮助观察对象归属。


















