如何返回发生的第一个异常?

Opa*_*pal 3 java functional-programming optional java-8 vavr

有一个名为 validate 的方法,它作为输入接受一个实例Option和一个Predicate- 两个参数(是的,我知道Option应该作为参数传递,但这里是简化的现实世界场景。现在,如果Option为空,我需要抛出NotFoundException。当它有一个与Predicate传递的值不匹配的值,它应该失败ForbiddenException。如果它有值并且它匹配谓词,则不会发生任何事情。

所以这将是:

                Option, Predicate
                     /\
          isEmpty() /  \ isDefined()  
                   /    \
            throw NFE    matches(Predicate)
                        / \
                    no /   \ yes 
                      /     \
                throw FE     end
Run Code Online (Sandbox Code Playgroud)

我有一些解决方案,但希望潜在的回答者能够清醒地回答这个问题;) 如果两个测试都失败,我的问题是第一个异常。如果我可以期待任何东西,我期待一个优雅的解决方案;) 允许所有 vavr 生物 ( Either, Validation, Try..)

其中一个想法是使用 double Option

Option
  .of(o.getOrElseThrow(NotFoundException::new))
  .filter(p)
  .getOrElseThrow(ForbiddenException::new);
Run Code Online (Sandbox Code Playgroud)

但这似乎有点尴尬。

在这里可以找到示例项目。

Fed*_*ner 5

在我看来,最好的选择是创建可读的代码,在这种情况下,这意味着使用两个if语句:

if (!o.isPresent()) throw new NotFoundException();
if (!p.test(o.get())) throw new ForbiddenException();
Run Code Online (Sandbox Code Playgroud)

对于将来需要维护此代码的任何人来说,它都简单、易读且直截了当。

尽管如此,如果你想要做的一些功能十岁上下的风格:

o.orElseThrow(NotFoundException::new);
o.filter(p).orElseThrow(ForbiddenException::new);
Run Code Online (Sandbox Code Playgroud)

使用 Java 9:

o.ifPresentOrElse(
    t -> if (!p.test(t)) throw new ForbiddenException(), 
    () -> throw new NotFoundException());
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这两种解决方案的简单和扁平代码。这是 Optionals 在 get 操作(get、orElse、orElseThrow、ifPresent...)后不会“过期”的好处的一个很好的例子,并且可以多次访问。 (2认同)