在jdk1.7及以后(外加其他的非hotspot虚拟机),String的intern()方法不再是把堆上面的字符串复制到字符串常量池中,并返回常量池里面此字符串的引用了。取而代之的是,inten()方法会在字符串常量池中记录首次出现的实例引用。
什么意思呢?假如说,有这样一段代码
String str2 = new StringBuilder("计算机").append("软件").toString();
当执行
System.out.println(str2 == str2.intern());
时候,会输出什么呢?
假如使用jdk1.6,那么将会输出false,因为str2.intern()返回的是复制到字符串常量池之后,常量池里面对象的引用,跟堆上的str2肯定不是一个对象。
而我是用的jdk1.8,结果就是true。按照刚才对这个方法的理解,intern()方法只是在字符串常量池里面记录了str2这个对象的引用,其实例数据仍然是堆上面的str2,所以结果是true。
再看一段代码
String s = "计算机"; String str2 = new StringBuilder("计算").append("机").toString(); System.out.println(str2 == str2.intern());
这次又是什么呢?
答案是false
如果你再读一遍刚才那句话,你会发现四个字,首次出现。
首次出现“计算机”这个字符串的是s这个变量,所以一旦有别的变量值为“计算机”的变量出现,无论怎么执行intern()方法,其返回的引用指向的仍然是第一次出现的s这个对象。所以
System.out.println(s == str2.intern());结果是true。
那这样呢?自己分析一下。
System.out.println(s.intern() == str2);