優(yōu)先使用整型池

上一建議我們解釋了包裝對象的比較問題,本建議將繼續(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í)例可以顯著提高空間和時間性能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容