我們知道Java引入包裝類型(Wrapper Types)是為了解決基本類型的實例化問題,以便讓一個基本類型也能參與到面向對象的編程世界中。而在Java 5中泛型更是對基本類型說了「不」,如想把一個整型放到List中,就必須使用Integer包裝類型。我們來看一段代碼:
//計算list中所有元素之和
public static int f(List<Integer>list){
int count=0;
for(int i:list){
count+=i;
}
return count;
}
接收一個元素是整型的List參數,計算所有元素之和,這在統計、報表項目中很常見,我們來看看這段代碼有沒有問題。遍歷一個列表,然後相加,應該沒有問題。那我們再來寫一個方法調用,代碼如下:</p>
public static void main(Stringargs){
List<Integer>list=new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(null);
System.out.println(f(list));
}
把1、2和空值都放到List中,然後調用方法計算,現在來思考一下會不會出錯。應該不會出錯吧,基本類型和包裝類型都是可以通過自動裝箱(Autoboxing)和自動拆箱(AutoUnboxing)自由轉換的,null應該可以轉為0吧,真的是這樣嗎?我們運行一下看看結果:
Exception in thread"main"java.lang.NullPointerException
運行失敗,報空指針異常,我們稍稍思考一下很快就知道原因了:在程序的for循環中,隱含了一個拆箱過程,在此過程中包裝類型轉換為了基本類型。我們知道拆箱過程是通過調用包裝對象的intValue方法來實現的,由於包裝對象是null值,訪問其intValue方法報空指針異常也就在所難免了。問題清楚了,修改也很簡單,加入null值檢查即可,代碼如下:
public static int f(List<Integer>list){
int count=0;
for(Integer i:list){
count+=(i!=null)?i:0;
}
return count;
}
上面以Integer和int為例說明了拆箱問題,其他7個包裝對象的拆箱過程也存在著同樣的問題。包裝對像和拆箱對象可以自由轉換,這不假,但是要剔除null值,null值並不能轉化為基本類型。對於此類問題,我們謹記一點:包裝類型參與運算時,要做null值校驗。