陷阱 - 不必要地使用原始包裝可能導致 NullPointerExceptions
有時,新 Java 的程式設計師將交替使用原始型別和包裝器。這可能會導致問題。考慮這個例子:
public class MyRecord {
public int a, b;
public Integer c, d;
}
...
MyRecord record = new MyRecord();
record.a = 1; // OK
record.b = record.b + 1; // OK
record.c = 1; // OK
record.d = record.d + 1; // throws a NullPointerException
我們的 MyRecord
類 1 依賴於預設初始化來初始化其欄位上的值。因此,當我們記錄時,a
和 b
欄位將被設定為零,c
和 d
欄位將被設定為 null
。
當我們嘗試使用預設的初始化欄位時,我們看到 int
欄位始終有效,但 Integer
欄位在某些情況下有效,而在其他情況下無效。具體來說,在失敗的情況下(使用 d
),會發生的情況是右側的表示式嘗試取消開啟 null
引用,這就是導致 NullPointerException
被丟擲的原因。
有幾種方法可以看看這個:
-
如果欄位
c
和d
需要是原始包裝器,那麼要麼我們不應該依賴於預設初始化,要麼我們應該測試null
。前者是正確的方法,除非對於null
狀態的欄位有明確的含義。 -
如果欄位不需要是原始包裝器,那麼使它們成為原始包裝器是錯誤的。除了這個問題,原始包裝器相對於原始型別還有額外的開銷。
這裡的教訓是不使用原始包裝型別,除非你真的需要。
1 - 本類不是良好編碼實踐的一個例子。例如,精心設計的類不會有公共欄位。但是,這不是這個例子的重點。