為什麼基本類型強轉object用==比較不相等?

沈西瑞


這個是要根據基本類型與賦值進行判斷的,我將從源碼與例子問答該問題。

基本類型的緩存池

boolean、byte、char、short、int、long這六個基本類型對應的Boolean、Byte、Character、Short、Integer、Long包裝類型都有一個XxxCache緩存池內部類,緩存類中存放了一些包裝類型的對象數組。

下圖為Integer類的內部緩存類IntegerCache,可以看出,該類內部緩存了-128~127數值的Integer數組。

下圖為Integer的valueOf(int i )方法,可以看出int轉Integer時會先查詢參數是否在緩存值範圍內,如果在就直接返回緩存數組中的整形引用,所以只要是通過Integer x = intNumber(即x = Integer.valueOf(intNumber))方式創建對象且賦值範圍在緩存值範圍內,引用的Integer對象都是一樣的,所以無論是用equals()還是==號的結果都為true,其它非浮點型(float、double)數據類型同理。當值不在緩存值範圍內時,valueOf()每次都會創建一個新的堆內存空間去存放新的數值,此時通過==結果判斷自然是false。

驗證例子

以下是一個根據題主問題寫的一個==判斷例子java與class文件

前面緩存池已經提過valueOf()是根據值是否在緩存池中判斷是否創建新對象,上面第一個int值5在緩存值中,當把Integer轉為Object時,傳的是地址引用,所以Object c引用的是IntegerCache數組中的對象地址,故第一個輸出true。

第二個int值為258超出緩存範圍時,每次調用valueOf()都會新建一個新的內存空間存放該值,所以第二個bb與cc引用的地址不同,輸出false。

第三個為浮點型,沒有緩存值,每次調用new創建新空間,所以輸出false。

通過源碼瞭解和編碼驗證可以加深對JDK原生對象的理解與更好的解決學習過程中遇到的的問題。


分享到:


相關文章: