截取并重试Java未处理的异常
我已经用一个catch-all处理程序编写了一个方法,但是我需要像未处理一样重新处理异常,以便调用堆栈更高层次的调用方能够处理它。实现这一点的简单方法是:截取并重试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
try {
...
} catch (Exception ex) {
// do something here...
// and rethrow
throw ex;
}
但问题是,由于throw
语句,Java要求此方法将自身声明为throws Exception
,这反过来又要求所有调用方处理异常或将自己声明为throws Exception
。等等,在呼叫链上
有没有简单的方法可以像当前方法没有处理异常一样重新抛出异常?你可以按照@radoh所说的做,只需将其包装成一个
RuntimeException
,但是这样做的一个缺点是你的stacktrace现在被污染了,并且会在声明抛出新RuntimeException(ex)的地方显示出有问题的行
另一种方法是使用LomboksSkillythrows
机制,如下所示:
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)
的地方显示有问题的行
另一种方法是使用LomboksSkillythrows
机制,如下所示:
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