陷阱 - 做出意想不到的空洞
在 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
发生,以便开发人员知道代码中存在问题。