String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。 --摘自《深入理解Java虚拟机》 page 61
先来看段代码:
运行结果:
相信很多人看到返回结果的时候都是很百思不得其解的,包括我也是看了好几遍才慢慢直到今天才理解了
讲之前先来了解下,jdk7以后常量池从方法区移到了堆,而且jdk7以后常量池既可以存放对象也可存放引用地址。那字符串常量池里放的什么?放的是字符串的引用。
下来看看 String s = new String("1"); 这句话都干了什么
- 创建一个引用 s
- 找到要生成的对象"1"在常量池中找是否有引用指向"1",如果找不到则堆上创建"1",常量池上创建引用指向"1"的地址。
- 因为new String()所以又在堆上开辟了地址,其值为"1";
- 最后再将这个值返回给引用s
通过这个过程我们不难发现指向new String(“1”)的和"1"的明显是两个引用故用==判断一定返回false。
看图可能更明白些:
同理,s3创建的时候是把4个东西放入了堆中,new String("1"),new String("11"),new String("1"),“1”,运行方法的时候发现常量池中没有“11”,那么会去堆中的new String("11"),这样其实两个的指向是相同的,所以为true
注意:本文归作者所有,未经作者允许,不得转载