繁体   English   中英

"如何在 Lambda 中抛出异常?"

[英]How to throw an exception inside a Lambda?

如何在 lambda 中抛出异常,例如在 Optional 的ifPresentOrElse中?

try {
   foo.bar(baz).ifPresentOrElse(theBar -> { 
      // A code inside here needs to throw a custom exception so the outside can handle it
      // It can't throw atm, and it is an unhandled exception here
   }, () -> { response.set(notFound()); }
} catch(CustomException e) {
  somethingImportantWhenExceptionIsThrown();
}

尽管在您的问题中没有明确提到,但我将假设您打算从ifPresentOrElse抛出一个已检查的异常。

首先,您应该尝试理解为什么不能抛出异常。 Consumer接口与Runnable ,只有一个抽象方法,这使其成为@FunctionalInterface 从文档:

请注意,可以使用 lambda 表达式、方法引用或构造函数引用创建函数式接口的实例。

这是Consumer接口的简化版本:

public interface Consumer<T> {

    void accept(T t); // <-- NO throws Exception
}

或者,您仍然可以使用旧的匿名内部类:

Consumer<Object> consumer = new Consumer<>() {
    @Override
    public void accept(Object o) { // <-- NO throws Exception
       // consume
    }
};

因此,您不能accept方法抛出已检查的异常。 这是不可能的设计。 但是,您可以选择以下选项之一:

  • 不推荐使用自定义ThrowingConsumerThrowingOptional类,它们可以抛出异常(因为您在它们的方法签名中声明了它们)。
  • 将检查过的异常包装在RuntimeException ,不需要在方法签名中声明,因此可以抛出。
  • 重写您的代码以不使用 lambda 表达式。

例如,对于最后一点:

Optional<Bar> barOpt = foo.bar(baz);
if(bar.isPresent()) {
    Bar bar = barOpt.get();
    try {
        // code that throws checked exception
    } catch(CustomException e) {
        somethingImportantWhenExceptionIsThrown();
    }
} else {
    response.set(notFound());
} 

解决方案是使用Project Lombok

并使用SneakyThrows注释包装此函数的方法,如下所示:

@SneakyThrows
void method() {
   try {
       foo.bar(baz).ifPresentOrElse(theBar -> { 
          throw()
       }, () -> { response.set(notFound()); }
   } catch(CustomException e) {
      somethingImportantWhenExceptionIsThrown();
   }
}

您可以使用 apache commons-lang3 库来做到这一点。

https:\/\/commons.apache.org\/proper\/commons-lang\/javadocs\/api-release\/org\/apache\/commons\/lang3\/function\/Failable.html<\/a>

Optional.of(obj).ifPresentOrElse(Failable.asConsumer(theBar -> {
    throw new Exception();
}), () -> {});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM