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

Java 何时或在什么情况下我应该使用Optional检查null?,java,java-8,Java,Java 8,我是否应该在Java8中始终使用可选的检查null 我在DAO层中使用它是一个好的实践吗?下面是我的DAO层的代码片段: public Optional<Tag> retrieveTagByValue(String tagValue) { Tag tag = null; try { tag = em.createNamedQuery("Tag.findByValue", Tag.class) .setParameter(

我是否应该在Java8中始终使用可选的检查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);
}
公共可选检索TagByValue(字符串tagValue){
Tag=null;
试一试{
tag=em.createNamedQuery(“tag.findByValue”,tag.class)
.setParameter(“tagValue”,tagValue)
.getSingleResult();
}捕获(noresulte异常){
System.out.println(e.getMessage());
}
返回可选。不可用(标记);
}

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

我认为您的示例是一个反模式,不必要地引入了
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();
    }
}
公共可选检索TagByValue(字符串tagValue){
试一试{
Tag Tag=em.createNamedQuery(“Tag.findByValue”,Tag.class)
.setParameter(“tagValue”,tagValue)
.getSingleResult();
返回可选。of(标签);
}捕获(noresulte异常){
System.out.println(e.getMessage());
返回可选的.empty();
}
}
这样,我们不是使用
Optional
来执行
null
检查,而是首先使用它来不引入
null

与捕获有意义的异常相比,在错误的情况下获取空的
可选的
,并且必须循环并解析标准输出以找出实际原因,这对调用方来说是否是一种改进仍有争议

但是,如果没有结果被认为是在该方法的正常操作范围内(与
Stream.findAny()
相比),则返回空的
可选
是可以的,但是,不必将消息打印到
System.out

我是否应该在Java8中始终使用可选的检查null

如果一个方法在Java7和更低版本中返回
null
,那么在Java8中应该使用
Optional.empty()
。使用
Optional
可以帮助您摆脱
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) {
        return Optional.empty();
    }
}
公共可选检索TagByValue(字符串tagValue){
试一试{
Tag Tag=em.createNamedQuery(“Tag.findByValue”,Tag.class)
.setParameter(“tagValue”,tagValue)
.getSingleResult();
返回可选。of(标签);
}捕获(noresulte异常){
返回可选的.empty();
}
}
使用
System.out…
进行日志记录被认为是不好的做法,您应该使用一些日志库

我在DAO层中使用它是一个好的实践吗

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

我想知道标签是否为空

比这是完美的情况下使用可选。你已经得到了关于如何重构代码的解释,但是想想这个方法的调用方


很明显,此方法可能返回一个不存在的结果-通过
可选。empty
表示,或者返回一个可能存在的结果,通过
可选。get/isPresent
等表示。这样,您可以强制调用方根据结果是否存在做出一些决定。返回引用时,情况并非如此

从客户的角度来处理这个问题。当你调用这个方法并得到一个可选的参数时,生活会更轻松吗?改进方法的方法:不要将异常写入系统。out@wero在我的服务层中,我想知道标记是否为null,如果为null,那么创建一个新标记,因此我想捕获NoResultException,然后打印一些内容。如果“不将异常写入System.out”,我该怎么办?谢谢~~您决定将设计不当的
NoResultException
转换为空结果(或带有空值的可选结果)。因此catch块应该是空的。也许我应该使用java.util.logging.Logger?@MarcuX我会使用SLF4J,它是通用日志框架的一个门面。