我們知道Java引入包裝類型(Wrapper Types)是爲了解決基本類型的實例化問題,以便讓一個基本類型也能參與到面向對象的編程世界中。而在Java5中泛型更是對基本類型說了“不”,如想吧一個整數放到List中,就必須使用Integer包裝類型。我們來看一段代碼:
/**
* @Description 計算list中所有元素之和
* @author 田爽
* @date 2015年4月9日下午8:36:32
*/
private static int f(List<Integer> list) {
int count = 0;
for (int i : list) {
count += i;
}
return count;
}
接收一個元素是整型的List參數,計算所有元素之和,這在統計、報表項目中很常見,我們來看看這段代碼有沒有問題。遍歷一個列表,然後相加,應該沒有問題。那我們再來寫一個方法調用,代碼如下:
public static void main(String[] args) {
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
at deep.Client.f(Client.java:23)
at deep.Client.main(Client.java:13)
運行失敗,報空指針異常,我們稍稍思考一下就知道原因了:在程序的for循環中,隱含了一個拆箱過程,在此過程中包裝類型轉換爲了基本類型。我們知道拆箱過程是通過調用包裝對象的intValue方法來實現的,由於包裝對象是null值,訪問其intValue方法報空指針異常也就在所難免了。問題清楚了,修改也很簡單,加入null值檢查即可,代碼如下:
/**
* @Description 計算list中所有元素之和
* @author 田爽
* @date 2015年4月9日下午8:45:33
*/
private 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值校驗。