引用數據類型自動拆裝箱

開發中既然有基本類型和包裝類型,肯定有些時候要在它們之間進行轉換。把基本類型轉換成包裝類型的過程叫做裝箱(boxing)。反之,把包裝類型轉換成基本類型的過程叫做拆箱(unboxing)

先看一段代碼

        // 第一組
        int a = 100;
        Integer b = 100;
        System.out.println( a == b ); // true

       
        // 第二組
        Integer a2 = 100;
        Integer b2 = 100;
        System.out.println( a2 == b2 ); // true

        // 第三組
        Integer a3 = 200;
        Integer b3 = 200;
        System.out.println( a3 == b3 ); // false

第一段代碼,基本類型和包裝類型進行 == 比較,這時候 b 會自動拆箱,直接和 a 比較值,所以結果爲 true。

第二段代碼,兩個包裝類型都被賦值爲了 100,這時候會進行自動裝箱,那 == 的結果會是什麼呢?引用數據類型進行==比較的時候,是不是進行的地址+值比較方式呢,那麼第二組的答案是false?但是,這次的結果卻是true。有點意外。

第三組代碼,還是兩個引用數據類型進行了==比較,好多人問,這不跟第二組一樣的嗎,都是連個引用類型比較,有什麼區別嗎,答案是true。但是真的嗎?運行代碼我們發現,這次答案是false。Why?

爲什麼?

最簡單的方式:看源碼。。。但是博主也是小白,對於源碼,我就不多做解釋,網上解釋的很清楚。

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

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

這段源碼看起來沒毛病,那麼毛病出在哪兒了呢,難不成是 IntegerCache 在作怪?你猜對了!

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);
        high = h;

        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;
    }
}

從這裏我們發現了問題了。-128 到 127 之間的數會從 IntegerCache 中取,然後比較,所以第二段代碼(100 在這個範圍之內)的結果是 true,而第三段代碼(200 不在這個範圍之內,所以 new 出來了兩個 Integer 對象)的結果是 false。

看完上面的分析之後,我們知道了:當需要進行自動裝箱時,如果數字在 -128 至 127 之間時,會直接使用緩存中的對象,而不是重新創建一個對象

對於其他的引用數據類型大致情況相似,感興趣的可以研究一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章