使用Java 8可选 - 转换逻辑

时间:2018-04-28 10:32:51

标签: java exception-handling java-8 optional

我正在尝试学习如何在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()没有发生。

3 个答案:

答案 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的关键是使用一种方法   消耗正确的值或产生替代品。