intern方法

intern方法的作用就是尝试将一个字符串放入StringTable中,如果不存在就放入StringTable并返回StringTable中的地址(如果这个字符串是通过2个new String()用‘+’链接的方式创建的,则StringTable内放置的就是new String生成的对象的地址,而不是实实在在的字符串值),如果存在的话就直接返回StringTable中的地址。这是jdk1.7、1.8版本中intern方法的作用,jdk1.6版本中有些不同,1.6中intern尝试将字符串对象放入StringTable,如果有则并不会放入,如果没有会把此对象复制一份,放入StringTable(此时字符串常量池放入的就是实实在在的字符串值), 再把StringTable中的对象返回。

题解

对于字符串常量池与字符串拼接提前没有了解的建议先看下这2片文章:

JVM虚拟机运行时数据区のStringTable 字符串常量池

字符串拼接操作在底层是如何操作的?

//这里的结果是false
String s1 = new String("a");
//new生成1个对象,同时把a放进了字符串常量池(常量池的a也是一个对象,所以这一步总共创建了2个对象),s1是new的a对象

s1.intern();
//intern方法在常量池中找a,发现常量池中有,就返回a的地址,由于没有变量接收,这一步相当于没有动作。

String s2 = "a";
//这种方式创建的字符串直接生成在常量池,由于常量池中字符串都是唯一的,所以s2是常量池中a

System.out.println(s1 == s2);
//s1是new的a对象 != s2是常量池中a

//========================================================================

//这里的结果jdk1.6是false,1.7 1.8上是true
String s3 = new String("b") + new String("c");
//通过字符串拼接的这种方式,只相当于再堆空间中有一个bc的对象,但是在字符串常量池并没有bc,s3是new的对象。

s3.intern();
//注意这里,仔仔细细看上面关于intern方法的1.6 与1.7 1.8以上的区别
//1.6:字符串常量池中没有bc,此时调用intern是复制了一份bc到常量池,2个对象。
//1.7 1.8 字符串常量池中没有bc,此时调用intern是复制了一份bc的地址到常量池,1个对象,一个对象的地址。

String s4 = "bc";
// 1.6:通过这种方式创建的字符串直接放入字符串常量池,发现常量池中有bc,所有此时s4是常量池的bc
//1.7 1.8:发现常量池中有bc,但是这个bc指向的是堆空间中有s3,所以此时s4最终指向的就是s3
System.out.println(s3 == s4);
//1.6:s3是new的对象!=s4是常量池的bc 是false
//1.7 1.8:s3是new的对象==s4最终指向的就是s3 是true

//========================================================================

//这里的结果是false
String s5 = new String("d") + new String("e");
//通过字符串拼接的这种方式,只相当于再堆空间中有一个de的对象,但是在字符串常量池并没有de,s5是new的对象。
String s6 = "de";
//此时常量池没有de,所以先把de放到字符串常量池,s6指向的就是常量池中的de
s5.intern();
//intern方法在常量池中找de,发现常量池中有,就返回de的地址,由于没有变量接收,这一步相当于没有动作。
System.out.println(s5 == s6);
//s5是new的对象 != s6指向的就是常量池中的de

本文地址:https://blog.csdn.net/ren365880/article/details/114004801