讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議26:提防包裝類型的null值 >

建議26:提防包裝類型的null值

我們知道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值校驗。