深刻了解java自動裝箱和拆箱

今天看《深刻理解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類靜態變量的計較,也能夠當作一種緩存吧。

相關文章
相關標籤/搜索