陷阱 - 做出意想不到的空洞
在 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 發生,以便開發人員知道程式碼中存在問題。