源碼分析128陷阱
如上圖所示,int類型數據超過127依舊能正常比較,但Integer類型就無法正確比較了
/*** Cache to support the object identity semantics of autoboxing for values between* -128 and 127 (inclusive) as required by JLS.** The cache is initialized on first usage. The size of the cache* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.* During VM initialization, java.lang.Integer.IntegerCache.high property* may be set and saved in the private system properties in the* sun.misc.VM class.*/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() {}}
IntegerCache類當中cache[]數組支持 JLS 所要求的自動裝箱值在 -128 到 127(含)之間的對象標識語義。
通過static靜態塊將catch數組初始化,如果沒有額外的配置,那么這個數組存儲的數的范圍就是-128~127之間。
如果我們的參數范圍在IntegerCache類的緩存數組的存儲范圍之內,我們就直接將存儲在cache數組中的這個Integer返回,否則的話我們就會new出一個新的Integer來保存我們的值。
對于基本數據類型來說,== 比較的是值。對于包裝數據類型來說,== 比較的是對象的內存地址。
Integer賦值時,值不在-128至127 之間就會重新開辟一塊內存地址存儲數據,此時用==比較出的內存地址就不一致了,就會返回false。
如何避免128陷阱
所有整型包裝類對象之間值的比較,全部使用 equals 方法比較。
說明:對于Integer var =?在-128至127 之間的賦值,Integer對象是在 IntegerCache.cache 產生會復用已有對象,這個區間內的 Integer 值可以直接使用==進行判斷,但是這個區間之外的所有數據,都會在堆上產生,并不會復用已有對象,推薦使用 equals 方法進行判斷。