我正在尝试学习如何在Java中使用Optional
- 但这似乎不正确我正在做的事情。
User user = null;
public AuthCheck(User user) throws Exception {
if (user == null) {
throw new Exception("No user!");
}
if (!(user.getStuff() != null && !user.getStuff().isEmpty())) {
throw new Exception("User has no stuff");
}
this.user = user;
}
这是我尝试使用Optional
转换它的方式:
Optional<UserOptional> user;
public AuthCheckOptional(Optional<UserOptional> user) throws Exception {
user.orElseThrow(() -> new Exception("No User!"));
user.map(UserOptional::getStuff)
.orElseThrow(() -> new Exception("User has no stuff"));
this.user = user;
}
我想我不需要两次单独的检查。此外,我相信我已经改变了逻辑,因为IsEmpty()
没有发生。
答案 0 :(得分:5)
您不希望使用Optional
作为输入参数;这是一种反模式。查看this article on DZone。
您可以采取以下措施来改进代码:
User user = null;
public authCheck(User user) {
Objects.requireNonNull(user, "No user!");
if (Objects.requireNonNull(user.getStuff(), "User has no stuff").isEmpty()) {
throw new RuntimeException("User has no stuff");
}
this.user = user;
}
(方法名称应以Java中的小写字母开头。)
你可以进一步压缩它,但问题是代码是否更清晰。
如果使用得当,null
没有任何问题。它意味着“未定义”,我们在Java中没有非空对象引用,就像在Kotlin或Scala中一样。
但也许你可以想一下如何创建User
对象,以便完全避免这个问题。您也许可以使用Builder设计模式。通常,重新思考代码可以避免这样的情况。
答案 1 :(得分:4)
我想警告你,这是疯狂的,令人困惑。我认为没有理由重新编写第一个好看的方法*。
但如果你真的想和Optional
一起玩,这里有一个方法链**:
Optional.of(
Optional.ofNullable(user)
.orElseThrow(() -> new Exception("No user!"))
)
.map(User::getStuff)
.filter(s -> !s.isEmpty())
.orElseThrow(() -> new Exception("User has no stuff"));
*还有改进的余地。 !(!a && !b)
仅表示a || b
。
final String stuff = user.getStuff();
if (stuff == null || stuff.isEmpty()) {
throw new Exception("User has no stuff");
}
**我认为getStuff
会返回String
。
答案 2 :(得分:2)
您错误地使用Optional<T>
类型,因此您无法获得任何好处,相反,它会使您的代码更难理解和维护。
您还应避免将Optional<T>
作为方法参数传递,请参阅here。
对于这种类型的逻辑,非可选方法更好,因此我强调你继续采用这种方法。
正如@Cay S. Horstmann在他的书中曾提到的那样:
有效使用Optional的关键是使用一种方法 消耗正确的值或产生替代品。