String.intern()方法解惑

在日常编码中,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。

你可能感兴趣的:(String.intern()方法解惑)