陷阱 - 做出意想不到的空洞
在 StackOverflow 上,我們經常在 Answers 中看到這樣的程式碼:
public String joinStrings(String a, String b) {
if (a == null) {
a = "";
}
if (b == null) {
b = "";
}
return a + ": " + b;
}
通常,這伴隨著一個斷言,這是一個最佳實踐來測試這樣的 null
以避免 NullPointerException
。
這是最佳做法嗎?簡而言之:不。
在我們可以說在我們的 joinStrings
中做這個是一個好主意之前,有一些潛在的假設需要質疑:
a
或 b
為空是什麼意思?
String
值可以是零個或多個字元,因此我們已經有了表示空字串的方法。null
對 ""
有什麼不同嗎?如果不是,那麼有兩種表示空字串的方法是有問題的。
null 是否來自未初始化的變數?
null
可以來自未初始化的欄位,也可以來自未初始化的陣列元素。價值可能是未經設計或未經意外的初始化。如果是偶然的,那麼這是一個錯誤。
null 表示不知道或缺失值嗎?
有時候,一個人可以擁有真正的意義; 例如,變數的實際值是未知的或不可用的或可選的。在 Java 8 中,Optional
類提供了一種更好的表達方式。
如果這是一個錯誤(或設計錯誤),我們應該做好嗎?
對程式碼的一種解釋是,我們通過在其位置使用空字串來使好成為意外的 null
。是正確的策略嗎?讓 NullPointerException
發生更好,然後在堆疊中進一步捕獲異常並將其記錄為 bug?
做好的問題在於它可能會隱藏問題,或者使其難以診斷。
這對程式碼質量有效/有效嗎?
如果一致地使用 make good
方法,那麼你的程式碼將包含許多防禦性null 測試。這將使它更長,更難閱讀。此外,所有這些測試和製造好都會對你的應用程式的效能產生影響。
綜上所述
如果 null
是一個有意義的值,那麼測試 null
案例是正確的方法。推論是,如果 null
值有意義,那麼應該在接受 null
值或返回它的任何方法的 javadoc 中清楚地記錄這一點。
否則,最好將意外的 null
視為程式設計錯誤,並讓 NullPointerException
發生,以便開發人員知道程式碼中存在問題。