截取并重试Java未处理的异常

截取并重试Java未处理的异常,java,exception-handling,Java,Exception Handling,我已经用一个catch-all处理程序编写了一个方法,但是我需要像未处理一样重新处理异常,以便调用堆栈更高层次的调用方能够处理它。实现这一点的简单方法是: try { ... } catch (Exception ex) { // do something here... // and rethrow throw ex; } 但问题是,由于throw语句,Java要求此方法将自身声明为throws Exception,这反过来又要求所有调用方处理异常或将自己声明为thr

我已经用一个catch-all处理程序编写了一个方法,但是我需要像未处理一样重新处理异常,以便调用堆栈更高层次的调用方能够处理它。实现这一点的简单方法是:

try {
   ...
} catch (Exception ex) {
   // do something here...
   // and rethrow
   throw ex;
}
但问题是,由于
throw
语句,Java要求此方法将自身声明为
throws Exception
,这反过来又要求所有调用方处理异常或将自己声明为
throws Exception
。等等,在呼叫链上


有没有简单的方法可以像当前方法没有处理异常一样重新抛出异常?

你可以按照@radoh所说的做,只需将其包装成一个
RuntimeException
,但是这样做的一个缺点是你的stacktrace现在被污染了,并且会在声明
抛出新RuntimeException(ex)的地方显示出有问题的行

另一种方法是使用Lomboks
Skillythrows
机制,如下所示:

public static void main(String[] args) {
    methodWithException();
}

private static void methodWithException() {
    try {
        throw new Exception("Hello");
    } catch (Exception e) {
        Lombok.sneakyThrow(e);
    }
}
stacktrace将保持不变,但不再需要声明
抛出异常


值得一读的是关于为什么你应该/不应该这样做的文章

你可以按照@radoh所说的去做,只需包装成一个
RuntimeException
,但它的一个缺点是你的stacktrace现在被污染了,并且会在你声明
抛出新RuntimeException(ex)
的地方显示有问题的行

另一种方法是使用Lomboks
Skillythrows
机制,如下所示:

public static void main(String[] args) {
    methodWithException();
}

private static void methodWithException() {
    try {
        throw new Exception("Hello");
    } catch (Exception e) {
        Lombok.sneakyThrow(e);
    }
}
stacktrace将保持不变,但不再需要声明
抛出异常


值得一读的是关于为什么你应该/不应该这样做的内容

你有两个选项(选中)例外:

  • 通过
    try
    /
    catch
    在方法中处理它们(这可能包括作为不同异常类型的重试)
  • 声明方法
    抛出异常
  • 如果您想像此方法未捕获异常一样重新引发异常,那么您唯一的选择是2


    注意:如果
    try
    块中的方法实际抛出
    Exception
    ,则只希望
    catch(异常e)
    。否则,捕获特定的异常类型。

    对于(选中的)异常,您有两个选项:

  • 通过
    try
    /
    catch
    在方法中处理它们(这可能包括作为不同异常类型的重试)
  • 声明方法
    抛出异常
  • 如果您想像此方法未捕获异常一样重新引发异常,那么您唯一的选择是2


    注意:如果
    try
    块中的方法实际抛出
    Exception
    ,则只希望
    catch(异常e)
    。否则,捕获特定的异常类型。

    与此完全相同。如果这里没有try/catch,您的方法将需要
    抛出异常
    (或者,至少,
    抛出
    try
    块中方法调用中实际抛出的异常类型)。
    catch(RuntimeException ex)
    。除非您的代码抛出一个选中的异常,否则您将需要一个用于
    RuntimeException
    的处理程序,以及另一个用于特定选中异常的处理程序-在
    RuntimeException
    中换行并重试。“使用全面捕获处理程序”很少是一个好主意。你为什么要这样做?以防万一:你终于知道了
    ,对吧?@adelphus:“任何东西”到底有多包容?
    try
    中的方法为
    throws
    声明了什么。如果这里没有try/catch,您的方法将需要
    抛出异常
    (或者,至少,
    抛出
    try
    块中方法调用中实际抛出的异常类型)。
    catch(RuntimeException ex)
    。除非您的代码抛出一个选中的异常,否则您将需要一个用于
    RuntimeException
    的处理程序,以及另一个用于特定选中异常的处理程序-在
    RuntimeException
    中换行并重试。“使用全面捕获处理程序”很少是一个好主意。你为什么要这样做?以防万一:你终于知道了
    ,对吧?@adelphus:“任何东西”到底有多包容?
    中的方法try
    throws
    声明了什么?skillythrow看起来正是我想要的-谢谢。是的,我知道这很糟糕。我觉得很糟糕,但我的另一个选择是编写一个jni库,它在Java编译器没有检查的情况下抛出。不太好。这条蛇看起来正是我想要的-谢谢。是的,我知道这很糟糕。我觉得很糟糕,但我的另一个选择是编写一个jni库,它在Java编译器没有检查的情况下抛出。不太好。我会这样做2.,但是有一个依赖于此方法的大量调用链,这反过来需要几百个方法都声明自己为
    抛出异常
    。这不是我的乐趣。@adelphus如果这些方法就是这么做的(即抛出异常),那么它们必须声明它们就是这么做的。@Boristeider…除非该方法是本机的。在这种情况下,它不必声明任何东西,也可以抛出任何东西。@adelphus我的观点更多地是从API方面而不是Java的要求。事实上,对于一个方法来说,无论什么要求都是声明它抛出一个已检查的异常,或者在异常发生时处理一个异常。但我从经验中知道,随机且毫无预兆的方法会让程序员有点……不开心。因此,我建议您1)创建一个
    AdelphusException
    2)将来自本机方法的任何内容包装为一,并3)声明您的API会抛出它们。我会这样做2.,但有大量调用链依赖于此方法,需要几百个方法来声明它们自己为
    抛出异常
    。这不是我的意思。@adelphus如果这些方法就是这么做的(即抛出异常),那么它们必须声明它们就是这么做的。@B