下圖為Integer的valueOf(int i )方法,可以看出int轉Integer時會先查詢引數是否在快取值範圍內,如果在就直接返回快取陣列中的整形引用,所以只要是透過Integer x = intNumber(即x = Integer.valueOf(intNumber))方式建立物件且賦值範圍在快取值範圍內,引用的Integer物件都是一樣的,所以無論是用equals()還是==號的結果都為true,其它非浮點型(float、double)資料型別同理。當值不在快取值範圍內時,valueOf()每次都會建立一個新的堆記憶體空間去存放新的數值,此時透過==結果判斷自然是false。
這個是要根據基本型別與賦值進行判斷的,我將從原始碼與例子問答該問題。
基本型別的快取池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原生物件的理解與更好的解決學習過程中遇到的的問題。