今天在學習程序中了解到一個現象,代碼如下:
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1==num2?true:false);
//***********************************************
Integer num3 = 200;
Integer num4 = 200;
System.out.println(num3==num4?true:false);
這串代碼,上面比較的是100裝箱后比較和200裝箱后比較,但是結果比較奇怪:

一個是true一個是false
首先要明確兩點:
- Integer是包裝類而不是基本資料型別,型別相比是要復雜一些的
- 裝箱程序在編譯器內進行了默認的valueOf()操作
所以該比較是比較的類,并且比較的是通過裝箱操作的包裝類,
回到重點,那么為什么100之間和200之間的比較完全不同?這涉及到Integer緩沖區的問題,我們可以查詢一下Integer內的valueOf()方法:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
解釋一下這串代碼,就是說裝箱操作并不是簡簡單單就裝進去就完事,其中需要判斷該數i是不是滿足 low <= i <= high
而緩沖區內:
int low = -128;
int high = 127;
而在這個范圍,就把這個裝箱后的結果取作cache陣列內原有的某個結果,cache的陣列區間為:
cache = new Integer[(high - low) + 1];//也就是256
譬如剛剛的例子中:
- 當num=100,此時判斷在這個范圍內,則將Integer(100)變成Integer cache[228],無論是地址還是內容都是cache[228],所以num1 == num2
- 當num=200,它就不在這個范圍內了,那么根據函式,直接回傳Integer(200),類的存盤是在堆中存盤的,num3,num4分別new了一個Integer,各自是不同的物件了,所以num3 !=num4
這里畫一個圖更容易理解,物件存盤在堆中,基本型別變數存盤在堆疊中,裝箱經過從堆疊到堆的轉換,這里創建兩個100和兩個200的變數進行裝箱操作,示例如下:

所以結論:
當顯式或者間接使用valuOf()方法時,若數值在Integer緩沖區范圍內,則無論創造多少次物件都是取的緩沖區陣列cache[]的原有物件,這些物件都是完全相同的;但如果不在緩沖區范圍,無論創建多少次物件都是新創建的,即使內容一致也不是同一個物件,
歡迎各位提出見解
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/421321.html
標籤:其他
