細節問題2:Integer什麼時候會使用常量池裏的值什麼時候會new一個?

細節問題2:Integer什麼時候會使用常量池裏的值什麼時候會new一個?

package classandobject;

public class Integer_Int {
    public static void main(String[]args){
      // 1)基本類型和包裝類型
        int a = 100;//常規量,
        Integer b = 100;//自動裝箱,但是100在-128到127之間,使用常量池存放,不用new一個
        System.out.println(a == b);//b拆箱,這裏就是比較值的大小了。

        // 2)兩個包裝類型
        Integer c = 100;//自動裝箱,但是100在-128到127之間,沒有使用new,默認放在棧裏邊,是地址引用,100存儲在方法區的常量池中
        Integer d = 100;//自動裝箱,但是100在-128到127之間,沒有使用new,默認放在棧裏邊,是地址引用,100存儲在方法區的常量池中
        System.out.println(c == d);//true,地址引用相同
        System.out.println(c==a);//true 自動拆箱
        Integer c_new = new Integer(100);
        System.out.println(c_new==c);//false,因爲地址引用不同
        // 3)常規量
        c = 200;//c = c.valueOf(200),200不在-128到127之間,所以會使用new創建對象
        d = 200;//也就是說這裏c,d都使用了new,

        System.out.println(c == d);//使用new創建的對象地址引用不同,false
        System.out.println(c.equals(d));//比較的是值,true

            }
}

在這裏插入圖片描述

解析
之前我們已經知道了,自動裝箱是通過 Integer.valueOf() 完成的,那我們就來看看這個方法的源碼吧。

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)//low=-128,high = 127
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);//發現沒有,裝箱過程可能會用到new
}
//我們來看一下條件是什麼:
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        int i = parseInt(integerCacheHighPropValue);//
        i = Math.max(i, 127);
        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);//基本都是h = i了。。。
        high = h;//high = i;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }
}

valueOf() 方法的實現比較簡單,就是先判斷值是否在緩存池中,如果在的話就直接返回緩存池的內容。在 Java 8 中,Integer 緩存池的大小默認爲 -128~127。編譯器會在自動裝箱過程調用 valueOf() 方法,因此

多個值相同且值在緩存池範圍內(-128~127)的 Integer 實例使用自動裝箱來創建,那麼就會引用相同的對象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章