本篇博客的内容能证明我上一篇博客中的推论
面试题原题:
public class TestDemo {
@Test
public void test01() {
String str1 = new StringBuilder("ja").append("va").toString();
String str2 = str1.intern();
System.out.println(str1 == str2);// 结果是false
String str3 = new StringBuilder("hello").append("world").toString();
String str4 = str3.intern();
System.out.println(str3 == str4);// 结果是true
}
}
关于String.intern()
的正确理解:以str3.intern();
为例,如果字符串常量中没有"helloworld"
这个字符串,则将这个字符串对象存入字符串常量池中,然后返回这个字符串对象。如果有则直接返回字符串常量池中的对应的那个对象,也就是被str4
引用。
在对象str3
的创建到输出true
这个过程中,如果按照我的解释:
String str3 = new StringBuilder(“hello”).append(“world”).toString();
在堆中的Eden区根据已有字符串常量"hello"
、"world"
创建一个新的字符串对象"helloworld"
,此时这个对象只是在堆中的Eden区,而字符串常量池则在堆的Old区。
String str4 = str3.intern();
str3调用intern方法,因为字符串常量池中没有"helloworld"
对象,则将这个对象存入字符串常量池中,然后将这个字符串对象返回。
很多人在这块没有搞懂,为什么我要这样解释,下面我娓娓道来。
这得涉及到 jvm 的内存管理的知识点。
当我们创建一个对象的时候,意味着需要申请一块空间用来存放这个新创建的对象。可这里有一个问题,jvm 如何管理内存的?