「技能分享」有效处理空值的10个技巧,学不会算我输
1.不要过于复杂
就其本身而言,处理null可能是一个复杂的问题,因此我们应使其尽可能整洁和明显。我在某些代码库中看到的一种非常糟糕的做法是在简单的空检查就足够了的地方使用Objects方法,Optional类,甚至使用Optional的单独方法。
这导致我检查该方法的来源,包含的内容,并想知道此方法与直接比较之间的区别是什么。当然,您的里程可能会有所不同,但是对我来说,这是我们应该避免的大量开销。
if (Optional.ofNullable(myVariable).isPresent()) // bad
if (Objects.nonNull(myVariable)) // better, but still bad
if (myVariable != null) // good
2.使用对象方法作为流谓词
虽然对象isNull和Objects ,nonNull不是典型的null检查的最佳选择,它们非常适合与流一起使用。与之相比,使用它们进行过滤或匹配的行的读取(可以说)要好得多。实际上,这就是在JDK中引入它们的原因。
myStream.filter(Objects::nonNull)
myStream.anyMatch(Objects::isNull)
3.永远不要将Null作为参数
这是良好编码的最重要原则之一,但是如果您还不了解它,就应该对它进行解释。传递null表示给定参数没有值可能是一个可行的选择。但是它有两个很大的缺点:
- 您需要阅读该函数的实现,并弄清楚它以及可能受影响的每个函数能否正确处理空值。
- 在更改函数的实现时,您必须始终小心,不要丢掉可能为用户处理空值的内容。否则,您必须搜索整个源代码以检查是否在任何地方传递了null。
通过接受永不传递null的原则,这两个问题将永远消失。那么带有可选参数的函数呢?很简单,只需使用不同的参数集重载函数即可:
void kill() {
kill(self);
}
void kill(Person person) {
person.setDeathTime(now());
}
顺便说一下,由于这两个缺点在单个类的范围内并不明显,因此在处理私有方法时可以放弃该规则。只要确保事物从外面是安全的即可。
4.验证公共API参数
您和您的团队可能会使用不成功传递null的原理,但是当公开公共API时,您无法控制其用户以及将其传递给函数的内容。因此,请务必检查传递给公共API的参数的正确性。
如果您唯一关心的是参数的无效性,请考虑使用Objects类中的requireNonNull函数:
public Foo(Bar bar, Baz baz) {
this.bar = Objects.requireNonNull(bar, "bar must not be null");
this.baz = Objects.requireNonNull(baz, "baz must not be null");
}
5. Leverage Optional
在Java 8之前,通常会在缺少值的情况下将方法返回null。这天生就是容易出错的,因为开发人员必须经常检查文档,或者如果缺少文档,则返回可能的null的基础源代码。
自从JDK 8发布以来,我们有了Optional类,该类专门设计用于指示可能缺少返回值。开发人员调用以Optional作为返回值的方法时,必须显式处理不存在该值的情况。
因此,在适用时,请使用Optional来包装您的返回类型。
Optional<String> makingYouCheck() {
// stuff
}
makingYouCheck().orElseThrow(ScrewYouException::new);
6.返回空集合而不是空
我们已经知道null不是方法的最佳返回值,并且我们可以使用 Optional类来指示该值可能丢失。但是当我们谈论集合时,情况有所不同。
由于集合可以包含任意数量的元素,因此它也可以包含…0个元素!在Collections类中甚至有特殊的emptyXxx方法返回此类集合。
因此,我们应该避免返回null或使用Optional使事情复杂化,并且在没有值可填充时返回空集合。
List<String> findSomething() {
if (someCondition) {
return Collections.emptyList();
}
// stuff
}
7.可选字段
正如我已经说过的那样,Optional旨在指示缺少的返回值。类字段是一种诱人的案例,它不是为设计而设计的,而且肯定不是必需的。通过封装,您应该完全控制字段的值,包括null。另一方面,将字段设置为显式可选可能会给您带来奇怪的问题,例如:
- 您应该如何为此类字段编写构造函数或设置方法?
- 即使在确定值存在的情况下,您也必须处理Optional。
- 自动映射器应如何处理这些字段?
因此,对字段使用直接引用,并仔细分析字段在任何给定点是否可以为空。如果您的班级得到了很好的封装,那么这应该很容易。
8.对空使用异常
您可能会看到人们使用null的一种奇怪情况是例外情况。这是一种固有的容易出错的做法,因为关键错误可以在系统的不同位置被忽略或重新出现,从而使调试变得很痛苦。因此,如果出现问题,请始终抛出异常,而不是返回null。
9.测试您的代码
此建议与各种错误有关,不仅是意外的null,而且它是如此重要,以至于我认为应该将其列入清单。使用类似于生产环境的环境彻底测试代码是防止NPE的好方法。切勿在未确保其正常工作的情况下发布一段代码。没有所谓的“不需要测试的快速,简单的修复程序”。
10.仔细检查
每当您假设某个引用不能为空时,请仔细检查您是否正确。在处理庞大的旧数据库或外部提供程序时,这一点尤其重要。对于前者,请花一些时间检查您要使用的列是否不包含任何空值,如果包含,则检查这些行是否可以将其放入您的系统中。
如果是外部提供商,则依赖合同,文档,如果不确定,请发送电子邮件或致电某人以确保您的假设正确。这可能很烦人,尤其是在使用文档记录不完善的API时,但涉及到null:安全胜过抱歉!
好啦!今天的分享到这里就结束了,希望大家持续关注马哥教育!
文章来源于网络,侵删!