?1.問題引入
分別引入了int和Integer變量,并進行比較
int b = 128;
int b1 = 128;Integer d = 127;
Integer d1 = 127;Integer e = 128;
Integer e1 = 128;System.out.println(b==b1);
System.out.println(d==d1);
System.out.println(e==e1);
System.out.println(e.equals(e1));
其輸出結果如下
我們可以看到以下三個問題
(1)當數據為int類型的時候,運行的結果為true,
(2)如果是封裝類型Integer的時候,數據為127的時候結果為true,但是到了128及以上就變成了false(128陷阱)
(3)使用equals時,同樣的數據運行結果卻為true
為什么會這樣呢?
2.==和equals
基本類型的數據的變量名和值都存在棧中(作為類的屬性的情況除外
==:
對于基本數據類型,比較的是棧中數據是否相同,只要數據沒有改變,其運行都會為true;
對于引用數據類型,則比較的是所指向對象的地址值是否相等
equals:
如果沒有對 equals 方法進行重寫,則相當于“==”,比較的是引用類型的變
量所指向的對象的地址值;重寫了,比較的是對象的值。
通過如上解釋就可以說明(1)、(3)問題了。
3.128陷阱原因
(1)什么是128陷阱
Integer 數據類型使用“==”比較時,如果對象值的范圍超出-128--127,那么兩個對象值相同的情況下,返回的結果是false。
(2)尋找原因
當Integer? a =?xxx時,其底層會自動轉換成為Integer a = Integer.valueOf(xxx)
所以讓我們一起看看 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存在范圍,在范圍內會返回cache數組,超過了就會重新new一個新的內存空間
?原因總結:Integer的ValueOf0方法當中,如果數值在最小值和最大值(-128~127)之間的數據都存儲在一個cache數組中,該數組相當于一個緩存,當我們在該范圍之間進行自動裝箱的時候,程序就直接返回該值在數組中的內存地址(cache數組的地址),所以在-128~127之間的數值用==進行比較是相等,而不在這個區間的數,需要新開辟—個內存空間,所以不相等。
(3)陷阱范圍
通過查看Integer源碼,我們可以看到其范圍是可以修改的,可自行嘗試
private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint 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_VALUEh = 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() {}}