陷阱 - 不必要地使用原始包裝可能導致 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

我們的 MyRecord1 依賴於預設初始化來初始化其欄位上的值。因此,當我們記錄時,ab 欄位將被設定為零,cd 欄位將被設定為 null

當我們嘗試使用預設的初始化欄位時,我們看到 int 欄位始終有效,但 Integer 欄位在某些情況下有效,而在其他情況下無效。具體來說,在失敗的情況下(使用 d),會發生的情況是右側的表示式嘗試取消開啟 null 引用,這就是導致 NullPointerException 被丟擲的原因。

有幾種方法可以看看這個:

  • 如果欄位 cd 需要是原始包裝器,那麼要麼我們不應該依賴於預設初始化,要麼我們應該測試 null。前者是正確的方法,除非對於 null 狀態的欄位有明確的含義。

  • 如果欄位不需要是原始包裝器,那麼使它們成為原始包裝器是錯誤的。除了這個問題,原始包裝器相對於原始型別還有額外的開銷。

這裡的教訓是不使用原始包裝型別,除非你真的需要。

1 - 本類不是良好編碼實踐的一個例子。例如,精心設計的類不會有公共欄位。但是,這不是這個例子的重點。