Integer.valueOf 源碼分析 原

1. 引言

在牛客網上看到這樣一道題目,判斷一下打印的結果

public static void main(String[] args){
	    Integer i1 = 128;
        Integer i2 = 128;
        System.out.println(i1==i2);

        Integer i3 = 100;
        Integer i4 = 100;
        System.out.println(i3==i4);
    }

剛開始看到是,是這樣來判斷的:因爲 Integer i1 = 128 這條語句,Integer 會啓用自動裝箱功能,調用 Integer.valueOf 方法返回一個 Integer 對象,因此這四個對象應該指向不同的地址,所以打印的結果是兩個 false。但是在 eclipse 運行結果如下,爲什麼會這樣呢?

運行結果

2. 分析

首先想到的就是 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);
    }

從中可以看出,valueOf 方法首先會判斷 i 值是否在一個範圍內,如果是的話,會從 IntegerCache 的 cache(其實是一個用 final static 修飾的數組) 中返回 Integer 對象,如果不在這個範圍內,會創建一個新的 Integer 對象。那麼就看一下這個範圍是什麼吧。跟到 IntegerCache 類內部,可以看到它定義的兩個變量,low 爲 -128,high 還未定義。

static final int low = -128;
static final int high;

通過 ctrl+F 查找 high 是什麼時候創建的,發現是在一個靜態代碼塊裏面:

static {
    // high value may be configured by property
    int h = 127;
    String integerCacheHighPropValue =
        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    if (integerCacheHighPropValue != null) {
        try {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        } catch( NumberFormatException nfe) {
            // If the property cannot be parsed into an int, ignore it.
        }
    }
    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;
}

從中可以看出,high 的值是由 h 決定的,h 一般爲 127。這說明,當 valueOf 傳入的參數值在 -128~127 之間,這些數值都會存儲在靜態數組 cache 中。因此,在 valueOf 方法裏,參數在 -128~127 之間,返回 Integer 對象的地址引用是一樣的,對於題目也有了正確的解答。

3. 總結

剛開始學編程時,如果碰到問題時,都是把報錯的信息賦值到百度或者谷歌上進行搜索,直接根據被人的踩坑經驗,按照他們給的步驟來解決問題,現在我又發現了一種更高效的解決方案 -- 直接看源碼,直接瞭解底層的實現,很快就可以解決問題了。所以,把自己的基礎打牢,勿以浮沙築高臺!

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