何时或在什么情况下我应该使用Optional来检查null?

时间:2017-05-17 15:29:34

标签: java java-8

我是否应该始终使用Optional来检查Java 8中的null?

我在DAO层使用它是一种好习惯吗?这是我的DAO图层的代码段:

public Optional<Tag> retrieveTagByValue(String tagValue) {
    Tag tag = null;
    try {
        tag = em.createNamedQuery("Tag.findByValue", Tag.class)
                .setParameter("tagValue", tagValue)
                .getSingleResult();
    } catch (NoResultException e) {
        System.out.println(e.getMessage());
    }
    return Optional.ofNullable(tag);
}

因为在我的服务层,我想知道标签是否为空,如果它是null,那么我创建一个新标签。所以我想知道在这种情况下我应该使用Optional,有没有更好的方法来改进这种方法?非常感谢!

3 个答案:

答案 0 :(得分:3)

我会将您的示例称为反模式,不必要地引入null,无论您执行后续null检查的方式如何。

考虑:

public Optional<Tag> retrieveTagByValue(String tagValue) {
    try {
        Tag tag = em.createNamedQuery("Tag.findByValue", Tag.class)
                .setParameter("tagValue", tagValue)
                .getSingleResult();
        return Optional.of(tag);
    } catch (NoResultException e) {
        System.out.println(e.getMessage());
        return Optional.empty();
    }
}

这样,我们就没有使用Optional来执行null检查,我们首先使用它来不引入null

对于调用者是否有改进,在错误的情况下得到一个空的Optional并且必须循环并解析标准输出以找出实际原因仍然是有争议的,与捕获一个有意义的例外。

但是如果没有结果被认为是在这个方法的正常操作范围内(与Stream.findAny()比较),返回一个空的Optional就没问题了,但是,它应该没有必要将邮件打印到System.out

答案 1 :(得分:2)

  

我是否应该始终使用Optional来检查Java 8中的null?

如果某个方法在Java 7中返回null,那么你应该在Java 8中使用Optional.empty()。使用Optional可以帮助你摆脱null检查和使代码更容易阅读。 Optional虽然在流中使用。

我会按以下方式重写代码:

public Optional<Tag> retrieveTagByValue(String tagValue) {
    try {
        Tag tag = em.createNamedQuery("Tag.findByValue", Tag.class)
            .setParameter("tagValue", tagValue)
            .getSingleResult();       
        return Optional.of(tag);
    } catch (NoResultException e) {
        return Optional.empty();
    }
}

使用System.out...进行日志记录并不是一种好习惯,您应该使用一些日志库。

  

我在DAO层使用它是一种好习惯吗?

就个人而言,我会用存储库替换DAO(查看Spring数据),我会在服务层使用Optional

答案 2 :(得分:1)

  

我想知道标签是否为空

这是完美案例使用Optional。你得到了关于如何重构代码的解释,但想想这个方法的调用者

您非常清楚此方法可能会返回不存在的结果 - 通过Optional.empty表示或可能存在的结果,通过Optional.get/isPresent表示等。这样您强制调用者根据结果是否存在做出一些决定。返回引用时根本不是这种情况。