在牛客網上看到這樣一道題目,判斷一下打印的結果java
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 運行結果以下,爲何會這樣呢?編程
首先想到的就是 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 還未定義。eclipse
static final int low = -128; static final int high;
經過 ctrl+F 查找 high 是何時建立的,發現是在一個靜態代碼塊裏面:code
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 對象的地址引用是同樣的,對於題目也有了正確的解答。orm
剛開始學編程時,若是碰到問題時,都是把報錯的信息賦值到百度或者谷歌上進行搜索,直接根據被人的踩坑經驗,按照他們給的步驟來解決問題,如今我又發現了一種更高效的解決方案 -- 直接看源碼,直接瞭解底層的實現,很快就能夠解決問題了。因此,把本身的基礎打牢,勿以浮沙築高臺!對象