String的intern()方法在JDK6及之后版本不同表现的原因解析

package string;

public class StringInternMethodPractice {
    public static void main(String[] args) {
        // append操作在堆内存中的字符数组
        StringBuilder stringBuilder1 = new StringBuilder("计算机").append("软件");
        // toString()将StringBuilder对象里的数组拷贝一份到String对象里头的数组
        String str1 = stringBuilder1.toString();
        System.out.println(str1.intern() == str1);

        StringBuilder stringBuilder2 = new StringBuilder("Ja").append("va");
        String str2 = stringBuilder2.toString();
        System.out.println(str2.intern() == str2);
    }
}

结果:
JDK6下输出false false ;JDK7下运行输出 true false

分析
1、JDK6,字符串常量池实现在永久代,intern()方法会把首次遇到的字符串实例复制到字符串常量池,返回的也是永久代里面这个字符串实例的引用。
调用str1的intern()方法,由于“计算机软件”这个位于堆的字符串首次出现,所以将该字符串实例复制到字符串常量池,并将字符串常量池的字符串实例引用返回。但是str1指向字符串实例在堆内存,所以两者比较为false。
Java这个位于堆的字符串不是首次出现,调用str2的intern()方法,就不需要复制了,返回永久代里面这个字符串实例的引用。所以两者比较为false。
2、JDK7,字符串常量池实现在堆中,intern()方法只需要在字符串常量池里记录一下首次出现的实例引用即可,不需要复制字符串。
调用str1的intern()方法,由于“计算机软件”这个位于堆的字符串首次出现,在字符串常量池里记录该对象的引用,并返回堆中该字符串实例的引用。所以两者比较为true。
Java这个位于堆的字符串不是首次出现,直接返回已经记录在字符串常量池里该对象的引用,虽然都是堆中的对象引用,但是不是同一个对象,所以返回false。

你可能感兴趣的:(String的intern()方法在JDK6及之后版本不同表现的原因解析)