当前位置: 首页 > 面试题库 >

如何从外部块重新抛出一个lambda块中的异常?

慕项明
2023-03-14
问题内容

使用以下代码,

void key(Key) throws SomeCheckedException {
}

void supplier(Supplier<Key> s) throws SomeCheckedException {
    ofNullable(s).ifPresent(s -> {                   //    |
        try {                                        //    |
            key(s.get());                            //    |
        } catch (final SomeCheckedException sce) {   //    |
            // sce is coming from key() method       //    |
            // How can I throw sce for outer method? //  --/
        }
    });
}

sce该如何抛出方法(supplier)方法一样的方法?

请注意,以上代码仅是示例。我需要在key(s.get())lambda表达式内。

void supplier(Supplier<Key> s) throws SomeCheckException {
    key(s.get());
}

问题答案:

如果您想以安全的方式处理已检查的异常,则需要一个辅助方法,该方法提供了将异常包装为的子类型的便利RuntimeException。这是一个使用Generic的类型安全性的帮助程序函数,以确保仅声明的异常将被重新抛出(除非您使用不安全的操作):

public static <E extends Throwable> void attempt(
    Consumer<Function<E,RuntimeException>> action) throws E {

    final class CarryException extends RuntimeException {
        final E carried;
        CarryException(E cause) {
            super(cause);
            carried=cause;
        }
    }

    try { action.accept( CarryException::new ); }
    catch(CarryException ex) { throw ex.carried; }
}

它支持任意方法action,该方法将接收将检查的异常类型临时包装到的函数RuntimeException。这种包装将是透明的,该方法attempt将正常完成或抛出原始的已检查异常E(如果发生,则抛出不相关的未检查异常)。

因此,您可以像这样使用它:

public static void processIterm(Supplier<Key> s)
    throws SomeCheckedException  {

    attempt( (Function<SomeCheckedException, RuntimeException> thrower) ->
        Optional.ofNullable(s).ifPresent(nonNull -> {
            try { key(nonNull.get()); } // assuming key may throw SomeCheckedException
            catch(SomeCheckedException  e) { throw thrower.apply(e); }
        }));
}

由于嵌套操作,编译器无法自动推断异常类型。上面的代码使用thrower参数类型的显式声明。或者,您可以使用辅助方法的类型调用,例如

ContainingClass.<SomeCheckedException>attempt( thrower ->
    Optional.ofNullable(s).ifPresent(nonNull -> {
        try { key(nonNull.get()); }
        catch(SomeCheckedException  e) { throw thrower.apply(e); }
    }));


 类似资料:
  • 如何在Lambda中处理和重新抛出异常?当我试图用try/catch块包围调用时,它只是在lambda表达式中捕获它。我在方法签名中有ServiceException,所以我只想重新抛出它。是可能还是我漏掉了什么?

  • @apiResponse似乎也没有更正响应类型。 如本问题所述,如何在swagger Codegen中处理多个响应/返回类型(204为空,400为非空等)? 我可以这样扔 但是有没有更好的方法来做到这一点呢?我只想将.getResponseBody()作为对象而不是字符串返回。 非常感谢。

  • 是否有一种方法可以找出try块中的哪一行抛出异常? 问题 堆栈跟踪只在catch块中显示OtherException的行 删除try/catch块并不简单,因为有许多声明为抛出的异常,需要捕获这些异常才能编译代码。 感觉应该有一个简单的方法来做到这一点。 注意:这段代码不是我写的;-)

  • 我有这样的情况,即活动调用管理器类调用提供者。 活动->管理器(带有asyncTask的方法)->提供程序 我应该如何将捕获的异常发送回活动?

  • 我们使用带有Log4j的springaop来登录我们的应用程序。我在应用程序中实现了@Before、@After、@posterhrowing建议。但我面临以下问题: 当任何异常在catch块中被捕获时,它不会调用@afterhrowing通知来打印错误堆栈跟踪。 我想为catch块中捕获的异常打印“错误堆栈跟踪”。意味着无论何时在try块中发生任何异常并被catch捕获,都应该调用一些建议来打印

  • 我的程序从控制台获取表示日期的输入,即。我会相应地存储所有数据 在这个try-catch块中,我检查变量“m”是否是正确的月份,关于日期,介于1和12之间。 如果“m”不是数字,则抛出。 我希望能够在if条件中抛出异常并终止显示抛出的错误和与之关联的消息的程序。