我正在尝试避免过度执行null检查,但与此同时,我想在需要使代码健壮的任何时候进行null检查。但是有时候我觉得它开始变得防御性很强,因为我没有实现API。然后,我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异常。什么是正确的方法,如何感觉平衡。这是我到目前为止收集的笔记:
让我举一个虚拟的例子,让我开始困惑:
这是界面的默认功能:
default void someFunction() {
// instantiaded foo and filters
foo = processFoo(foo, filters);
// do some operations with foo
// null check if processFoo's contract returns null (description in the implementation)
}
实施:
Foo processFoo(foo, filters) {
// Should I null check foo and filters?
// Operations with foo.someFields
// Operations with filters.someFields
return foo; // If I null check then I should return some exception or null to the caller function.
// If I don't null check just return received foo.
}
答案 0 :(得分:4)
一般来说,在控制调用的过程中,我从不检查null,但是如果我的代码可以被其他人调用,则我会强制执行检查,因为您在谈论API规范,所以您可能会检查输入参数并抛出IllegalArgumentException。
当然,在大多数情况下,这不是必需的,当您拥有NPE时,某个地方存在潜在的错误,但是,如果您不能完全控制呼叫,则肯定需要付出额外的努力。 (特别是如果您的API将被频繁调用,则需要一些帮助您跟踪/识别错误调用模式的东西)。
在设计API时,除了架构本身之外,您还必须专注于维护/故障排除和安全性,尤其是如果API是公开的(这意味着还要清理每个参数)。
答案 1 :(得分:1)
如果您已在项目中实现分层,则执行空检查的好地方是从外部接收数据的层。例如:控制器,因为它从用户那里接收数据...或网关,因为它从存储库接收数据。
但是,如果您有能力控制方法的返回值以不返回null
,那将是很好的。这将使您能够编写更少的空检查代码,因为您可以通过这种缺失值来“鸵鸟”。 Java为我们提供了这样的类/方法,例如Optional
,Java 11的Reader.nullReader()
,Writer.nullWriter()
和Collections.empty{List|Map|Set|...}()
中的空集合。
当然,您可以创建自己的null对象,以便它可以以不影响程序使用的方式变形。
答案 2 :(得分:1)
在这里扮演恶魔的拥护者,是因为似乎有些人发表评论似乎不喜欢“ null”的概念或在程序中使用它。
“ null”并不是丝毫可以避免的东西,如果您尝试这样做,将会遇到失败。创建对象并为此类对象在内存中分配空间是不必要的,因为如果您的代码在收到“ null”值时会中断,那么在处理它根本无法处理的对象时,它肯定也会中断。不仅如此,而且使用许多Java方法也会遇到失败。
如果可以避免使用'null'并为代码提供更好的处理方式,请这样做。否则,请勿折断背部和脊椎,以免受伤。
最后,回答您的问题:
不确定 是否可以返回“空”值时,您可以输入空检查。例如,如果调用未创建的方法,并且该方法被设计为返回对象,并且该方法可能返回空值,则为此情况添加特殊检查。如果您知道永远不会收到null值(例如,您自己设计了一个方法永远不会返回'null'),则无需进行任何null检查。
此外,如果您仅使用内部或私有方法,并且您知道没有像在示例中那样传递空参数,那么也不必添加空检查。这也适用于您提到的构造函数实例。否则,作为公共方法的经验法则,最好使用空检查,即使仅抛出IllegalArgumentException或返回失败也是如此。