String對象intern方法的分析和理解


以下測試結果都是在HotSpot JDK1.7中運行的

源碼:

public class Intern{
    public static void main(String[] args){
        String str1 = new StringBuilder("計算機").append("系統").toString();
        System.out.println(str1.intern() == str1);
        String str2 = new StringBuilder("In").append("tern").toString();
        System.out.println(str2.intern() == str2);
        String str4 = new StringBuilder("ja").append("va").toString();
        System.out.println(str4.intern() == str4);
        String str3 = new StringBuilder("計算機").append("系統").toString();
        System.out.println(str3.intern() == str3);
        System.out.println(str1.intern() == str3.intern());
    }
}

 

運行結果:

true
false
false
false
true

分析:

1. JDK1.7中,HotSpot已經開始逐步“去永久化”,也就是說對於jvm內存分布中的方法區(即我們常說的常量區)里邊的類,對象常量等信息,已經並不一定是永久存在的了,也可能會被GC回收掉

2. JDK1.7中,對String的intern方法做了修改,在1.6及以前的JDK中,intern方法會在調用時先去常量池中查看是否有相同的字符串(equals()),如果有那就返回常量的引用,如果沒有就復制字符串實例放到常量區,然后再返回對常量的引用,所以如果用JDK1.6 及以前的版本運行上邊代碼的話,輸出結果都是false。JDK1.7中,intern方法不會再復制實例,而是在常量池中記錄首次出現的字符串(equals())的實例引用。在上邊的例子中,調用str1.intern()方法時,由於計算機系統String對象是首次出現,此時就會把此對象實例的引用放到常量池中,返回的也是常量池中對首次出現的實例的引用,所以是true。對於Intern和java,由於並不是第一次出現(在加載class文件和執行java命令時已經存儲到常量池里),所以輸出是false,對於第二次出現的計算機系統,由於不是首次出現,所以是false

3. 對於str1.intern() == str3.intern() 由於返回的都是對首次創建計算機系統字符串實例的引用,所以是true

總結:

1. 1.7JDK中intern()方法始終返回的也是常量池的引用信息,只不過不同的是1.7中返回的是相同字符串(equals())首次創建時的引用地址

2. 常量池中不直接存儲字符串常量,而存儲的是首次創建此字符串時的引用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM