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

package string;

public class StringInternMethodPractice {
    public static void main(String[] args) {
        // append操作在堆內(nèi)存中的字符數(shù)組
        StringBuilder stringBuilder1 = new StringBuilder("計算機(jī)").append("軟件");
        // toString()將StringBuilder對象里的數(shù)組拷貝一份到String對象里頭的數(shù)組
        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);
    }
}

結(jié)果:
JDK6下輸出false false ;JDK7下運(yùn)行輸出 true false

分析
1、JDK6,字符串常量池實現(xiàn)在永久代,intern()方法會把首次遇到的字符串實例復(fù)制到字符串常量池,返回的也是永久代里面這個字符串實例的引用。
調(diào)用str1的intern()方法,由于“計算機(jī)軟件”這個位于堆的字符串首次出現(xiàn),所以將該字符串實例復(fù)制到字符串常量池,并將字符串常量池的字符串實例引用返回。但是str1指向字符串實例在堆內(nèi)存,所以兩者比較為false。
Java這個位于堆的字符串不是首次出現(xiàn),調(diào)用str2的intern()方法,就不需要復(fù)制了,返回永久代里面這個字符串實例的引用。所以兩者比較為false。
2、JDK7,字符串常量池實現(xiàn)在堆中,intern()方法只需要在字符串常量池里記錄一下首次出現(xiàn)的實例引用即可,不需要復(fù)制字符串。
調(diào)用str1的intern()方法,由于“計算機(jī)軟件”這個位于堆的字符串首次出現(xiàn),在字符串常量池里記錄該對象的引用,并返回堆中該字符串實例的引用。所以兩者比較為true。
Java這個位于堆的字符串不是首次出現(xiàn),直接返回已經(jīng)記錄在字符串常量池里該對象的引用,雖然都是堆中的對象引用,但是不是同一個對象,所以返回false。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容