我是否应该始终使用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,有没有更好的方法来改进这种方法?非常感谢!
答案 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
表示等。这样您强制调用者根据结果是否存在做出一些决定。返回引用时根本不是这种情况。