通过new String("xxx")
创建了两个对象。
结论:一个或两个
通过new String("xxx")
创建的对象取决于字符串常量池中是否已存在内容为"xxx"的字符串对象。
-
如果字符串常量池中不存在内容为"xxx"的字符串对象:
- 在堆内存中创建一个新的字符串对象,内容为"xxx"。
- 字符串常量池中创建一个新的字符串对象,内容为"xxx"。
- 返回堆内存中的字符串对象的引用。
-
如果字符串常量池中已存在内容为"xxx"的字符串对象:
- 在堆内存中创建一个新的字符串对象,内容为"xxx"。
- 返回堆内存中的字符串对象的引用。
综上所述,无论字符串常量池中是否已存在相同内容的字符串对象,new String("xxx")
语句都会在堆内存中创建一个新的字符串对象,并返回其引用。但并不一定会在常量池中创建对象。
流程:
-
当JVM在编译阶段加载读取到“xyz”的时候,首先会检查堆中的String常量池,也就是常量缓冲区。检查是否已经有了"xyz"常量对象,如果有,则不会再次创建"xyz"常量对象,并直接返回该字符串的引用地址;如果没有,则创建一个"xyz"常量对象,并为该对象分配一个内存地址002返回;
-
当JVM在运行阶段加载读取到new关键字的时候,JVM会在堆中为其创建一个对象,即new String(),并为其分配内存地址001,而堆中这个对象的内容是上面"xyz"常量对象的引用地址002,换句话说这个堆中存的就是常量池中"xyz"的引用地址002;
-
最后,s 是对当前堆中001号对象的一个地址引用,s本身不是一个对象,s只是一个String类型的变量而已!