4

大多数静态代码分析工具建议不要捕获通用(特别是未经检查的)异常,如 RuntimeExceptions 和 Errors。

除非此异常屏障在顶层可能是合理的,否则通常不会在较低级别。不幸的是,在重写/修复已经存在的代码时,这可能很难实现,因为潜在的错误和 RuntimeExceptions 的潜在可能性可能过高。此外,深入研究较低的代码级别以获得一些足够合理的异常概念以捕获而不是通用捕获,这主要是一项非常耗时且复杂的任务。

您是否知道将此类通用(未经检查的)异常分解为更具体的异常的任何工具或最佳实践?

说我们有这样的东西:

try
{
    somethingReallyComplex();
}
catch (RuntimeException | Error ex)
{
    Logger.error(this, ex.getClass().getName() + " while doing something really complex", ex)
}

try 块可以包含一个非常复杂的代码问题,其中包含各种不同的 RuntimeExceptions 和 Errors,这些都是有意义的捕获。但是,我怎样才能最有效地分析此代码以将 RuntimeException 分解为 NullPointerException、ArrayIndexOutOfBoundException ......无论是什么合理的?

是否有任何工具可以分析此类代码并就其中最常见的 RuntimeExceptions 等提供建议?

你如何着手解决这个问题?

主观或客观的“阈值”在哪里说:“不,我只是将其保留为 RuntimeException 并添加抑制注释?”

4

4 回答 4

7

捕捉一般异常最重要的是在哪里捕捉它们,而不是. 如果你在一个中心位置执行此操作,即所谓的异常屏障,它位于调用堆栈的较高位置,那么这正是你应该做的。如果您在代码中间(或多或少任意点)这样做,那将是一个不好的做法。

于 2012-07-25T17:10:06.543 回答
2

举证责任不应该由您承担,而应由希望您更改代码的工具承担。任何合理的静态分析工具都会给出特定警告背后的基本原理,使您能够评估在特定情况下忽略该警告的影响。(大多数警告的存在是因为它们标记的代码通常是有问题的,而不是因为它总是如此。)

在某些情况下捕获 Exception 是正确的做法,因为您的恢复逻辑非常笼统,不需要区分异常,例如,如果您实现以下内容:“如果出现问题,请重试两次。如果仍然没有工作,记录异常,通知用户,然后继续”。这实际上取决于您的异常处理程序的作用。

于 2012-07-25T17:18:58.700 回答
0

虽然不建议我通常捕获一般异常,但毕竟我要做的唯一事情就是写入日志并继续前进。

如果您必须根据发生的问题执行不同的清理任务,那么在尝试之后有 6 个或任何 catch 块可能会很有用。

于 2012-07-25T17:08:51.723 回答
0

在我看来,代码的每一部分都应该捕获它知道如何处理的异常,并且它抛出的所有已检查异常都应该具有与这段代码相关的含义。一个基本机制是将所有处理的异常包装到此方法抛出的已检查异常的类型中。此规则的例外 (huhu) 是 RuntimeExceptions,主要是您不应尝试捕获的错误(请参阅错误 javadoc)。

所以对我来说,你的 try{} 块中的每个方法都应该抛出带有与方法相关的语义的检查异常。并且递归地你在所有这些方法上做同样的事情,但我看不出有任何工具足够聪明来为你做这件事。

于 2012-07-25T17:23:20.083 回答