Integer 中的緩存類IntegerCache

2014年去某公司筆試的時候遇到這麼一道題:

複製代碼
public class Test {
    public static void main(String[] args) {
        Integer int1 = Integer.valueOf("100");
        Integer int2 = Integer.valueOf("100");
        System.out.println(int1 == int2);
    }
}
複製代碼

問打印的結果的多少? 但是我回答的是false, 後來仔細想想應該沒有這個簡單,就翻了下JDK的源碼,發現:

複製代碼
public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }

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

        private IntegerCache() {}
    }
複製代碼

原來Integer把-128到127(可調)的整數都提前實例化了。 這就解釋了那道面試題的答案,原來你不管創建多少個這個範圍內的Integer用ValueOf出來的都是同一個對象。

但是爲什麼JDK要這麼多此一舉呢? 我們仔細想想, 淘寶的商品大多數都是100以內的價格, 一天後臺服務器會new多少個這個的Integer, 用了IntegerCache,就減少了new的時間也就提升了效率。同時JDK還提供cache中high值得可配置,

這無疑提高了靈活性,方便對JVM進行優化。

 

參考Long的源碼:

複製代碼
private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }
複製代碼

Long也做了緩存,只是沒有提供調整機制, 在Short中類似:

複製代碼
private static class ShortCache {
        private ShortCache(){}

        static final Short cache[] = new Short[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Short((short)(i - 128));
        }
    }

Integer和int的區別?在什麼時候用Integer和什麼時候用int

/*
 * int是java提供的8種原始數據類型之一。Java爲每個原始類型提供了封裝類,Integer是java爲int提供的封裝類。int的默認值爲0,
 * 而Integer的默認值爲null
 * ,即Integer可以區分出未賦值和值爲0的區別,int則無法表達出未賦值的情況,例如,要想表達出沒有參加考試和考試成績爲0的區別
 * ,則只能使用Integer
 * 。在JSP開發中,Integer的默認爲null,所以用el表達式在文本框中顯示時,值爲空白字符串,而int默認的默認值爲0,所以用el表達式在文本框中顯示時
 * ,結果爲0,所以,int不適合作爲web層的表單數據的類型。
 * 在Hibernate中,如果將OID定義爲Integer類型,那麼Hibernate就可以根據其值是否爲null而判斷一個對象是否是臨時的
 * ,如果將OID定義爲了int類型,還需要在hbm映射文件中設置其unsaved-value屬性爲0。
 * 另外,Integer提供了多個與整數相關的操作方法,例如,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。

 */

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