在日常编码中,String.intern()不算是一个常用的方法,但是很多同学在面试的时候都会碰到这个问题(鄙视一下这些面试官),这里我们基于内存来详细分析一下这个方法。
String.intern()
是一个Native方法,它的作用是:如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。先上代码:
String str1 = new StringBuilder("i'm").append(" T").toString();
System.out.println(str1.intern()==str1);
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);
这段代码在JDK1.6中运行,会得到两个false,而在JDK1.7和1.8中运行会得到一个ture和一个false。这个差异的原因是:
- 在JDK1.6中,
intern()
方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中这个字符串实例的引用,而由StringBuilder
创建的字符串实例在Java堆上,所以必然不是同一个引用。 - 而JDK1.7中已经将运行时常量池从永久代移除,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。因此
intern()
返回的引用和由StringBuilder
创建的那个字符串实例是同一个。 - 对
str2
的比较返回false是因为“java”这个字符串在执行StringBuilder.toString()
之前已经出现过,字符串常量池中已经有它的引用了,不符合“首次出现”的原则,而“i'm T”这个字符串则是首次出现的,因此返回true。
网友评论