1. 程式人生 > >Integer值比較的問題

Integer值比較的問題

最近開發中,遇到一個問題,兩個Integer型別的值,進行比較時,明明兩個值是相等的,但是用==比較卻是false,結果這是一個很low的問題,記錄一下

程式碼片段:

        Integer a = 100;
        Integer b = 100;
        System.out.println("100 == 100 結果是:" + (a == b));
       100 == 100 結果是:true

上面是正常的,列印結果是true,可是下面的程式碼段,就出現問題了

        Integer a = 300;
        Integer b = 300;
        System.out.println("300 == 300 結果是:" + (a == b));
        300 == 300 結果是:false

問題出現了,為什麼Integer型別的300一樣的值,比較卻不相同呢? 我們看下原始碼裡
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

這是jdk對Integer的複製,我們看到它對傳進來的變數值做了一個判斷,如果i>=-128 && i <= 127,他會從一個為cache的數組裡直接取,那麼我們在看看cache陣列是什麼
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;

	    // 先例項化了一個大小為 (127 + 128 + 1)這樣大小的陣列
            cache = new Integer[(high - low) + 1];
            int j = low;
            
            // 迴圈往數組裡賦值,賦的什麼呢,就是一個Integer的物件
            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() {}
    }

所以,我們從上面可以得到,如果變數值在-127和128之間,他會直接從事先例項化好的數組裡面取,==我們知道,比較的是堆裡面的物件,從數組裡取,肯定是一樣的例項,所以為true;  但是如果不在這個範圍內,他會重新 new Integer()物件,那對於Integer a = 300, Integer b = 300;實際是哪個等於 new了兩個物件,這時候 == 比較,肯定是false

結論就是:如果是Integer封裝類,比較值相等,我們儘量採用 equals()比較,因為equals比較的是值,所以不管是100,還是300,a.equals(b)都是true

                   如果是原始型別int,則可以用==比較