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

在 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 发生,以便开发人员知道代码中存在问题。