当可选项为空时如何返回?

27 浏览
0 Comments

当可选项为空时如何返回?

我喜欢现在Java标准库中有Optional。但是有一个基本的问题一直困扰着我,我还没有找到最好的解决方法(最容易阅读、理解、美观和最短的):

如果Optional为空,如何从一个方法中返回?

我正在寻找一个通用解决方案,适用于不同数量的Optional组合和代码块的大小。

在下面的示例中,我将尝试说明我的意思:

void m1() {
    // 当我得到一个Optional:
    Optional o = getOptional();
    // 如果它为空,我想要返回
    if (!o.isPresent()) return;
    // 在整个方法中,每次想要获取值时都必须调用Optional.get:
    System.out.println(o.get());
    // 这非常丑陋和冗长!
}
void m2() {
    // 如果我返回null,如果值不存在:
    String s = getNullabe();
    if (s == null) return;
    // 然后我可以直接使用该值:
    System.out.println(s);
}

这个问题涉及如何同时获得上述两个示例的优点:Optional的类型安全性和可空类型的简洁性。

其余的示例更详细地说明了这一点。

void m3() {
    // 另一方面,如果我希望在值不存在时抛出异常,那么这个方法很简洁:
    String s = getOptional()
        .orElseThrow(IllegalStateException::new);
    System.out.println(s);
}
void m4() {
    Optional o = getOptional();
    if (!o.isPresent()) return;
    // 当然,我可以为非Optional的字符串声明一个新变量:
    String s = o.get();
    System.out.println(s);
    // 但是旧变量仍然在整个方法的作用域中,这很丑陋和烦人。
    System.out.println(o.get());
}
void m5() {
    // 这种方式简洁而美观:
    getOptional().ifPresent(s -> {
        System.out.println(s);
        // 但是额外的嵌套层级很烦人,而且在一个大型lambda中编写所有代码感觉不对。
        getOtherOptional().ifPresent(i -> {
            // 此外,有更多的Optional值使得代码非常奇怪且难以阅读,而使用可空类型则不会增加额外的嵌套,看起来很好也易于阅读。
            System.out.println("i: " + i);
            // 无论哪种方式,它都无法适用于所有情况。
        });
    });
}
Optional getOptional() {
    throw new UnsupportedOperationException();
}
Optional getOtherOptional() {
    throw new UnsupportedOperationException();
}
String getNullabe() {
    throw new UnsupportedOperationException();
}

如何在Optional为空时从一个方法中返回,而不必在方法的其余部分使用get,无需声明额外的变量并且不需要额外的块嵌套?

或者如果无法满足所有要求,那么处理这种情况的最佳方法是什么?

0