在很久之前的一次面試中,面試官問了我這麼一個問題:「如今有 Integer a = 56, b = 56, c = 180, d = 180; 請問:a == b ,c == d 是否成立,也就是是否爲true?」java
我當時知道 a == b 是 爲true,c == d 是爲false的,我也是這麼回答的。接着面試官問我,「爲何呢?」面試
而後我就不知道了。那個的確是否是很清楚爲何會這樣,不過雖然那個時候這個問題沒有回答出來,可是其餘問題都回答得不錯,而且這是一面,到了二面的時候也回答得不錯,因此最後仍是拿下來了這個offer。數組
雖然那個時候拿到了offer,可是沒有回答出這個問題,我仍是挺在乎的,後面我也去研究了一下。緩存
首先我經過代碼驗證一下我那次面試的回答:ide
1 //定義兩組Integer變量 2 Integer a = 56, b = 56, c = 180, d = 180; 3 System.out.println("a == b:" + (a == b)); 4 System.out.println("c == d:" + (c == d));
打印結果以下:ui
1 a == b:true 2 c == d:false
接下來咱們來找一下到底爲何?this
當咱們按照 :spa
1 Integer a = 56, b = 56, c = 180, d = 180;
定義變量的時候其實就至關於:code
1 Integer a = Integer.valueOf(56), b = Integer.valueOf(56), c = Integer.valueOf(180), d = Integer.valueOf(180);
咱們去看 Integer.valueOf() 的源碼:orm
1 /** 2 * Returns an {@code Integer} instance representing the specified 3 * {@code int} value. If a new {@code Integer} instance is not 4 * required, this method should generally be used in preference to 5 * the constructor {@link #Integer(int)}, as this method is likely 6 * to yield significantly better space and time performance by 7 * caching frequently requested values. 8 * 9 * This method will always cache values in the range -128 to 127, 10 * inclusive, and may cache other values outside of this range. 11 * 12 * @param i an {@code int} value. 13 * @return an {@code Integer} instance representing {@code i}. 14 * @since 1.5 15 */ 16 public static Integer valueOf(int i) { 17 if (i >= IntegerCache.low && i <= IntegerCache.high) 18 return IntegerCache.cache[i + (-IntegerCache.low)]; 19 return new Integer(i); 20 }
有以上的源碼和註釋中會發現從jdk1.5開始就有了這個方法,當傳入的參數"i"大於等於 IntegerCache.low 且小於等於IntegerCache.high 的時候返回 IntegerCache.cache[i + (-IntegerCache.low)],不然 new 一個Integer變量返回,顧名思義IntegerCache 應該就是Integer的緩存用的相關靜態類,這個時候咱們能夠繼續去看 IntegerCache 的源碼:
1 /** 2 * Cache to support the object identity semantics of autoboxing for values between 3 * -128 and 127 (inclusive) as required by JLS. 4 * 5 * The cache is initialized on first usage. The size of the cache 6 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. 7 * During VM initialization, java.lang.Integer.IntegerCache.high property 8 * may be set and saved in the private system properties in the 9 * sun.misc.VM class. 10 */ 11 12 private static class IntegerCache { 13 static final int low = -128; 14 static final int high; 15 static final Integer cache[]; 16 17 static { 18 // high value may be configured by property 19 int h = 127; 20 String integerCacheHighPropValue = 21 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); 22 if (integerCacheHighPropValue != null) { 23 try { 24 int i = parseInt(integerCacheHighPropValue); 25 i = Math.max(i, 127); 26 // Maximum array size is Integer.MAX_VALUE 27 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); 28 } catch( NumberFormatException nfe) { 29 // If the property cannot be parsed into an int, ignore it. 30 } 31 } 32 high = h; 33 34 cache = new Integer[(high - low) + 1]; 35 int j = low; 36 for(int k = 0; k < cache.length; k++) 37 cache[k] = new Integer(j++); 38 39 // range [-128, 127] must be interned (JLS7 5.1.7) 40 assert IntegerCache.high >= 127; 41 } 42 43 private IntegerCache() {} 44 }
有上面的源代碼能夠看出,在Integer裏定義了一個私有的靜態內部類 IntegerCache ,在其中定義了 靜態Integer數組 cache ,長度爲 high = 127 和 low = -128 之間的差值,而且存儲的是 從 low到high,即-128到127的值。
總結:
由以上的分析咱們能夠知道,當咱們 Integer a = 56, b = 56, c = 180, d = 180; 的時候:
1. 若是定義的變量在 -128到127之間,則是直接去緩存cache裏的值,因此若是數值一致則對應的地址值也會一致,因此咱們用 == 判斷兩個值是否相等,是返回 true的;
2. 若是定義的變量不在 -128到127之間,則經過new Integer(int i)的方式建立數值,而且每次都會從新new一個對象,這就致使每次的對象的數值即便同樣可是地址值不一致,因此此時用 == 判斷兩個值是否相等就不如咱們所願了;
3. 因此咱們遇到包裝類 Integer定義的變量的時候,若是要判斷兩個變量的值是否相等,則使用 equals來判斷,儘可能不要用 == 的來判斷。