天天看點

在Java中避免NullPointerException

我object != null要避免很多NullPointerException。

有什麼替代方法:

解決方案:

在我看來,這似乎是一個相當普遍的問題,初級和中級開發人員往往會在某個時候遇到這些問題:他們要麼不知道,要麼不信任他們所參與的合同,并且防禦性地檢查了null。另外,在編寫自己的代碼時,他們傾向于依靠傳回空值來表示某些内容,是以要求調用者檢查空值。

換句話說,在兩種情況下會出現空檢查:

如果為null,則表示合同中的有效回複;和

如果不是有效的回應。

(2)容易。使用assert語句(斷言)或允許失敗(例如 NullPointerException)。斷言是1.4中新增的一個未被廣泛使用的Java功能。文法為:

或者

where<condition>是一個布爾表達式,<object>是一個對象,其toString()方法的輸出将包含在錯誤中。

一個assert語句抛出一個Error(AssertionError如果條件是不正确的)。預設情況下,Java會忽略斷言。您可以通過将選項傳遞-ea給JVM來啟用斷言。您可以啟用和禁用單個類和程式包的斷言。這意味着盡管我的測試幾乎沒有顯示斷言對性能的影響,但是您可以在開發和測試時使用斷言來驗證代碼,并在生産環境中禁用它們。

在這種情況下,不使用斷言是可以的,因為代碼隻會失敗,這就是使用斷言時會發生的情況。唯一的差別是,有了斷言,它可能會更早地發生,以更有意義的方式出現,并可能帶有額外的資訊,這可以幫助您弄清楚為什麼它出乎意料。

(1)有點難。如果您無法控制正在調用的代碼,那麼您将陷入困境。如果null為有效響應,則必須檢查它。

但是,如果是您控制的代碼(通常是這種情況),那就是另一回事了。避免使用null作為響應。使用傳回集合的方法很容易:幾乎總是一直傳回空集合(或數組)而不是null。

使用非集合,可能會更困難。以這個為例:如果您具有以下接口:

在Parser中,原始的使用者輸入會找到要執行的操作,也許是在您實作某項功能的指令行界面時。現在,如果沒有适當的操作,您可以使合同傳回null。這将導緻您正在談論的空檢查。

另一種解決方案是從不傳回null,而使用Null Object模式:

比較:

這是一個更好的設計,因為它可以導緻更簡潔的代碼。

也就是說,對于findAction()方法來說,抛出帶有有意義的錯誤消息的Exception異常是完全适當的-特别是在這種情況下,您依賴于使用者輸入。對于findAction方法抛出一個異常,比對一個沒有解釋的簡單NullPointerException進行抛出的調用方法要好得多。

或者,如果您認為try / catch機制太醜陋,而不是什麼都不做,則您的預設操作應向使用者提供回報。