1

简短版本: 我如何捕获java.lang.Error特定代码部分中的所有抛出以记录它们,并允许它们传播调用堆栈,就好像我根本没有捕获它们一样?

长版...

在一段代码中,我想捕获所有内容java.lang.Error以便记录它们。但我也想让Error继续在调用堆栈中向上工作,这样行为就好像我根本没有抓住它一样。

此外,我想捕获并记录所有java.lang.Exceptions,然后让它们也传播调用堆栈。

我试过这个...

    } catch (Throwable e) {
        e.printStackTrace();
        throw e;
    } 

...但问题是我必须修改调用堆栈中更高的每个方法才能 throw Throwable,其中一些方法不是我要修改的(我的方法被第三方框架中的方法调用)。

我会对某种包裹技术感到满意,我会把它放在Throwable别的东西里然后扔掉,但我更愿意让任何java.lang.Errors 以它们自然的方式向上传播,就好像我根本没有抓住它们一样。

建议?

编辑: 有人问“我为什么要这样做?”。我认为这是一个很好的问题,我将澄清:这是我公司使用的框架。它取决于 jar 中包含的其他框架,系统管理员可能忘记包含这些框架。在这种情况下,代码中的某些位置会出现 NoClassDefFoundError。但只有用户在浏览器中看到此错误,在服务器日志中找不到。我想记录它,以便系统管理员可以知道发生了此错误,因为他将有处理它的说明。

4

1 回答 1

6

你说:“我试过这个……”

    } catch (Throwable e) {
        e.printStackTrace();
        throw e;
    } 

您应该尝试:

    } catch (Error e) {
        e.printStackTrace();
        throw e;
    } 

错误不是检查异常。您不必在任何方法签名中声明它们。只要把它放在你最外层的方法中,它就会做你想做的事。

编辑:

如果你还想捕获并重新抛出异常,让我们考虑一下。你有三种 Throwable:Error、Exception 和 RuntimeException。不检查 Error 和 RuntimeException,但检查不是 RuntimeException 的 Exception。

所以,你可以对 RuntimeException 做同样的事情,就像我们对 Error 做的一样:

    } catch (RuntimeException e) {
        e.printStackTrace();
        throw e;
    } catch (Error e) {
        e.printStackTrace();
        throw e;
    } 

而不是 RuntimeException 的 Exception 呢?要理解的是,这些是检查异常,如果它们没有在代码调用的方法中声明,那么它们将不会被抛出。所以你不需要捕捉/重新抛出它们。如果某些调用的方法实际上抛出了这样的异常,那么您将不得不捕获/重新抛出它并将您的方法标记为抛出该异常,但无论如何您都必须这样做,因为它们来自外部方法正在调用的方法。

于 2013-03-03T20:04:19.743 回答