250429-String的创建
答案
A
错因
不知道常量池中的字符串也算是对象(StringObject) ;其次:new String("xyz")的过程是先判断常量池中是否有"xyz",如果有,则只在堆空间中new一个String对象,如果没有,则在常量池中新建一个"xyz"字符串常量,然后在堆中new一个String对象
AI润色后:
在 Java 中,字符串字面量(如 "xyz"
)会被保存在字符串常量池中,而常量池中的字符串也是 String
类型的对象。
当执行 new String("xyz")
时,Java 会先检查字符串常量池中是否存在 "xyz"
:
- 如果常量池中没有,则先在常量池中创建一个
"xyz"
对象; - 然后,无论常量池是否已有
"xyz"
,new String("xyz")
都会在堆内存中创建一个新的String
对象,这个新对象的值就是"xyz"
,即它内部引用的是常量池中的对象。
因此,这一行代码最多会创建两个对象:一个在常量池,一个在堆中。最少会创建一个对象(堆中的)。
new String()的底层原理
堆空间中 new
出来的 String
对象是如何“指向” "xyz"
的?
这是个很好的问题。
String s = new String("xyz");
这个语句的核心步骤如下:
"xyz"
是一个字面量,在编译时就进入常量池;"xyz"
会变成一个常量池中的String
对象;new String("xyz")
会在堆中创建一个新对象,调用构造方法:
public String(String original) { this.value = original.value; }
所以新对象会复制常量池中"xyz"
对象的字符数组(char[]
或byte[]
,取决于版本)。
🔹 结论:
- 堆中的
String
对象 并不直接指向常量池中的对象; - 它 复制了常量池中对象的底层字符数组,作为自己的数据(在较新版本可能直接复用字符数组,视 JVM 实现)。
🧠 总结一句话:
new String("xyz")
创建的是一个新的 String
对象,它的内容来自于常量池中的 "xyz"
,复制字符数组,但它们是两个不同的对象,内容相同,引用不同。