今天看《深刻理解JAVA虛擬機》,發現本身對自動裝箱和拆箱有一些誤解,在此寫下來:緩存
問題一、code
Integer a = 3; Integer b = 3;
請問 a==b 返回 true 仍是 false ?對象
開始堅決果斷選擇了false ,明顯 a和b不是同一個對象。結果親自運行這段代碼發現返回true。源碼
問題二、虛擬機
Integer c = 333; Integer d= 333;
請問 c==d 返回 true 仍是 false ?it
親自試驗以後問題2返回false。c.equals(d) 返回true。變量
不解了吧?若是問題1返回true,問題2爲何返回false呢?方法
首先說下自動裝箱:Integer自動裝箱時是調用valueOf(int i)來完成自動裝箱的,再來看Integer的valueOf(int i)的源碼:總結
public static Integer valueOf(int i) { final int offset = 128; if (i >= -128 && i <= 127) { // must cache return IntegerCache.cache[i + offset]; } return new Integer(i); }static
原來-128-127之間的整數返回的是緩存,大於這個區間的才返回新的Integer對象。
再來看看Integer的equals方法:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; } 不難看出Integer對象的equals方法比較的是Integer拆箱以後的值。自動拆箱是調用initValue方法來實現的。
總結:對於基本類型的包裝類型,Byte、Short、Integer、Long、Character 都存在這樣的緩存機制,你們在使用字面量初始化對象,而後進行== 比較的時候須要留心注意。 Float、Double沒有這樣的機制。 Boolean 比較特殊,字面量的初始化後,== 操做會返回Boolean類靜態變量的計較,也能夠當作一種緩存吧。