上一建議我們解釋了包裝對象的比較問題,本建議將繼續(xù)深入討論相關(guān)問題,首先看如下代碼:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(input.hasNextInt()){
int ii = input.nextInt();
System.out.println("\n===="+ii+" 的相等判斷======");
//兩個通過new產(chǎn)生的Integer對象
Integer i =new Integer(ii);
Integer j = new Integer(ii);
System.out.println("new產(chǎn)生的對象:" + (i==j));
//基本類型轉(zhuǎn)為包裝類型后比較
i=ii;
j=ii;
System.out.println("基本類型轉(zhuǎn)換的對象:" + (i==j));
//通過靜態(tài)方法生成一個實(shí)例
i=Integer.valueOf(ii);
j = Integer.valueOf(ii);
System.out.println("valueOf產(chǎn)生的對象:" + (i==j));
}
}
輸入多個數(shù)字,然后按照3種不同的方式產(chǎn)生Integer對象,判斷其是否相等,注意這里使用了“==”,這說明判斷的不是同一個對象。我們輸入三個數(shù)字127、128、555,結(jié)果如下:
====127 的相等判斷======
new產(chǎn)生的對象:false
基本類型轉(zhuǎn)換的對象:true
valueOf產(chǎn)生的對象:true
====128 的相等判斷======
new產(chǎn)生的對象:false
基本類型轉(zhuǎn)換的對象:false
valueOf產(chǎn)生的對象:false
====555 的相等判斷======
new產(chǎn)生的對象:false
基本類型轉(zhuǎn)換的對象:false
valueOf產(chǎn)生的對象:false
很不可思議呀,數(shù)字127的比較結(jié)果竟然與其他兩個數(shù)字不同,它的裝箱動作所產(chǎn)生的對象竟然是同一個對象,valueOf產(chǎn)生的也是同一個對象,但是大于127的數(shù)字128和555在比較過程中所產(chǎn)生的卻不是同一個對象,這是為什么?我們一個一個來解釋。
- new產(chǎn)生的Integer對象
new聲明的就是要生成一個新的對象,沒二話,這是兩個對象,地址肯定不等,比較結(jié)果為false。 - 裝箱生成的對象
對于這一點(diǎn),首先要說明的是裝箱動作是通過valueOf方法實(shí)現(xiàn)的,也就是說后兩個算法是相同的,那結(jié)果肯定也是一樣的,現(xiàn)在的問題是:valueOf是如何生成對象的呢?我們來閱讀一下Integer.valueOf的實(shí)現(xiàn)代碼:
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);
}
這段代碼的意思已經(jīng)很明了了,如果是-128到127之間的int類型轉(zhuǎn)換為Integer對象,則直接從cache數(shù)組中獲得,那cache數(shù)組里是什么東西,代碼如下:
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
cache是IntegerCache內(nèi)部類的一個靜態(tài)數(shù)組,容納的是﹣128到127之間的Integer對象。通過valueOf產(chǎn)生包裝對象時,如果int參數(shù)在﹣128和127之間,則直接從整型池中獲得對象,不在該范圍的int類型則通過new生成包裝對象。
明白了這一點(diǎn),要理解上面的輸出結(jié)果就迎刃而解了,127的包裝對象是直接從整型池中獲得的,不管你輸入多少次127這個數(shù)字,獲得的對象都是同一個,那地址當(dāng)然都是相等的。而128、555超出了整型池范圍,是通過new產(chǎn)生一個新的對象,地址不同,當(dāng)然也就不相等了。
以上的解釋也是整型池的原理,整型池的存在不僅僅提高了系統(tǒng)性能,同時也節(jié)約了內(nèi)存空間,這也是我們使用整型池的原因,也就是在聲明包裝對象的時候使用valueOf生成,而不是通過構(gòu)造函數(shù)來生成的原因。順便提醒大家,在判斷對象是否相等的時候,最好是用equals方法,避免用“==”產(chǎn)生非預(yù)期結(jié)果。
注意 通過包裝類的valueOf生成包裝實(shí)例可以顯著提高空間和時間性能。