陷阱 - 做出意想不到的空洞

在 StackOverflow 上,我們經常在 Answers 中看到這樣的程式碼:

public String joinStrings(String a, String b) {
    if (a == null) {
        a = "";
    }
    if (b == null) {
        b = "";
    }
    return a + ": " + b;
}

通常,這伴隨著一個斷言,這是一個最佳實踐來測試這樣的 null 以避免 NullPointerException

這是最佳做法嗎?簡而言之:不。

在我們可以說在我們的 joinStrings 中做這個是一個好主意之前,有一些潛在的假設需要質疑:

ab 為空是什麼意思?

String 值可以是零個或多個字元,因此我們已經有了表示空字串的方法。null"" 有什麼不同嗎?如果不是,那麼有兩種表示空字串的方法是有問題的。

null 是否來自未初始化的變數?

null 可以來自未初始化的欄位,也可以來自未初始化的陣列元素。價值可能是未經設計或未經意外的初始化。如果是偶然的,那麼這是一個錯誤。

null 表示不知道缺失值嗎?

有時候,一個人可以擁有真正的意義; 例如,變數的實際值是未知的或不可用的或可選的。在 Java 8 中,Optional 類提供了一種更好的表達方式。

如果這是一個錯誤(或設計錯誤),我們應該做好嗎?

對程式碼的一種解釋是,我們通過在其位置使用空字串來使好成為意外的 null。是正確的策略嗎?讓 NullPointerException 發生更好,然後在堆疊中進一步捕獲異常並將其記錄為 bug?

做好的問題在於它可能會隱藏問題,或者使其難以診斷。

這對程式碼質量有效/有效嗎?

如果一致地使用 make good 方法,那麼你的程式碼將包含許多防禦性null 測試。這將使它更長,更難閱讀。此外,所有這些測試和製造好都會對你的應用程式的效能產生影響。

綜上所述

如果 null 是一個有意義的值,那麼測試 null 案例是正確的方法。推論是,如果 null 值有意義,那麼應該在接受 null 值或返回它的任何方法的 javadoc 中清楚地記錄這一點。

否則,最好將意外的 null 視為程式設計錯誤,並讓 NullPointerException 發生,以便開發人員知道程式碼中存在問題。