专栏首页北京马哥教育「技能分享」有效处理空值的10个技巧,学不会算我输

「技能分享」有效处理空值的10个技巧,学不会算我输

当我们开始使用Java进行编程时,很多人会把null值当做敌人,并且害怕NullPointerExceptions,下面给大家分享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表示给定参数没有值可能是一个可行的选择。但是它有两个很大的缺点:

  1. 您需要阅读该函数的实现,并弄清楚它以及可能受影响的每个函数能否正确处理空值。
  2. 在更改函数的实现时,您必须始终小心,不要丢掉可能为用户处理空值的内容。否则,您必须搜索整个源代码以检查是否在任何地方传递了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:安全胜过抱歉!

好啦!今天的分享到这里就结束了,希望大家持续关注马哥教育!

原文链接:https://www.magedu.com/84377.html

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 让你的 Python 代码优雅又地道

    如果说优雅也有缺点的话,那就是你需要艰巨的工作才能得到它,需要良好的教育才能欣赏它。

    小小科
  • wtfPython—Python中一些奇妙的代码

    wtfPython是github上的一个项目,作者收集了一些奇妙的Python代码片段,这些代码的输出结果会和我们想象中的不太一样; 通过探寻产生这种结果的内部...

    小小科
  • 浅入深谈:一道Python面试题,让我明白了殊途同归,却开始怀疑自己

    怀疑了人生半天,本来还想黑,WTF Python…然后才想通是自己太生疏......

    小小科
  • Java函数式开发——优雅的Optional空指针处理

    空闲时会抽空学习同在jvm上运行的Groovy和Scala,发现他们对null的处理比早期版本Java慎重很多。在Java8中,Optional为函数式编程的n...

    哲洛不闹
  • Android开发 - 处理 null 和 预防空指针异常(NullPointerException) 的一些经验

    比如: 通过intent传参到新的目标 activity,而且一定需要这个参数,那么在新的目标activity中 onCreate方法中 判断中这个参数,如果n...

    zhangyunfeiVir
  • Mysql中的Null值

    在大对数编程语言中,逻辑表达式的值只有两种:True,False。但是在关系型数据库中的逻辑表达式并非两种,而是三值逻辑的表达式(True、False、Unkn...

    DH镔
  • Nullable Reference Types 可空引用类型

    但如果想避免NullReferenceException的发生,确实需要做很多麻烦的工作。

    solenovex
  • 测者的测试技术手册:Java中的null类型

    null是一个非常非常特殊的类型,对于每一个测试人员都要十分小心null的存在的可能性。同时null也让很多RD头疼,甚至连Java的设计者都成人null是一个...

    Criss@陈磊
  • Java中的null“类型”

    null是一个非常非常特殊的类型,对于每一个测试人员都要十分小心null的存在的可能性。同时null也让很多RD头疼,甚至连Java的设计者都成人null是一个...

    Criss@陈磊
  • Vue + Element UI 实现权限管理系统 前端篇(九)

    前台显示需要后台数据,我们这里先把前后端交互接口定义好,没有后台的时候,也方便用mock模拟。

    朝雨忆轻尘

扫码关注云+社区

领取腾讯云代金券