这涉及字符串加载到字符串常量池的原理:由于字符串字面量先在编译阶段加载到class常量池中,然后在类加载阶段从类常量池中加载到运行时常量池中,当字符串字面量被调用的时候,会检查字符串常量池中是否包含该字符串对象,如果已经包含,则直接返回该字符串对象的引用,如果没有,则创建该字符串字面量对应的对象。
String s = "hello"
结合上面描述的字符串常量池原理。String s = "hello"
会创建0个或1个对象,首先字面量"hello"在编译阶段被加载到class文件中的类常量池中,在类加载到虚拟机的阶段,“hello”会被加载到运行时常量池中,当这句代码被执行的时候,JVM会检查字符串常量池中是否存在内容为"hello"的字符串对象,如果有则不会再创建该对象,如果没有,则会创建该对象。
String s = new String("hello")
在语句 String s = new String("hello");
中,实际上可能会创建一个或者两个对象,具体取决于字符串常量池中是否已经存在相同内容的字符串。和上面分析一样,首先字面量"hello"在编译阶段被加载到class文件中的类常量池中,在类加载到虚拟机的阶段,“hello”会被加载到运行时常量池中,当这句代码被执行的时候,JVM会检查字符串常量池中是否存在内容为"hello"的字符串对象,如果有则不会再创建该对象,如果没有,则会创建该对象。
-
如果字符串常量池中不存在内容为 "hello" 的字符串对象:在这种情况下,会创建两个对象:
- 一个是在堆内存中通过
new String("hello")
创建的新的字符串对象,这个对象在堆上分配内存。 - 另一个是常量池中的
"hello"
字符串常量,会被创建并存储在常量池中。
- 一个是在堆内存中通过
-
如果字符串常量池中存在内容为 "hello" 的字符串对象`:在这种情况下,只会创建一个对象:
- 仅会在堆内存中创建一个新的字符串对象,而字符串常量池中会重复使用已经存在的字符串对象。