Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;Don';t捕获一般异常&引用;但如何解开它们呢?_Java_Exception_Error Handling_Static Analysis - Fatal编程技术网

Java &引用;Don';t捕获一般异常&引用;但如何解开它们呢?

Java &引用;Don';t捕获一般异常&引用;但如何解开它们呢?,java,exception,error-handling,static-analysis,Java,Exception,Error Handling,Static Analysis,大多数静态代码分析工具建议不要捕获一般(尤其是未检查的)异常,如运行时异常和错误 除非这个例外障碍在顶层可能是合理的,否则它通常不在较低的层。 不幸的是,在重写/修复现有代码时,这可能很难实现,因为潜在错误和运行时异常的可能性可能过高。 此外,深入研究较低的代码级别以获得一些异常的想法,而不是泛型捕获,这通常是一项非常耗时和复杂的任务 您知道有什么工具或最佳实践可以将此类一般(未经检查的)异常分解为更具体的异常吗 假设我们有这样的东西: try { somethingReallyComp

大多数静态代码分析工具建议不要捕获一般(尤其是未检查的)异常,如运行时异常和错误

除非这个例外障碍在顶层可能是合理的,否则它通常不在较低的层。 不幸的是,在重写/修复现有代码时,这可能很难实现,因为潜在错误和运行时异常的可能性可能过高。 此外,深入研究较低的代码级别以获得一些异常的想法,而不是泛型捕获,这通常是一项非常耗时和复杂的任务

您知道有什么工具或最佳实践可以将此类一般(未经检查的)异常分解为更具体的异常吗

假设我们有这样的东西:

try
{
    somethingReallyComplex();
}
catch (RuntimeException | Error ex)
{
    Logger.error(this, ex.getClass().getName() + " while doing something really complex", ex)
}
try块可能包含非常复杂的代码,其中包含各种不同的运行时异常和错误,这些异常和错误是有意义的。 但我如何才能最有效地分析这段代码,将RuntimeException分解为NullPointerException、ArrayIndexOutOfBoundException。。。有什么合理的吗

是否有任何工具可以分析此类代码,并对其中最常见的运行时异常等给出建议

你是如何开始解决这个问题的

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

虽然不建议这样做,但我通常会捕获一般异常,毕竟我要做的唯一一件事就是写入日志并继续


如果您必须根据爆炸的情况执行不同的清理任务,那么在尝试后使用6个或其他捕获块可能会很有用

捕获一般异常最重要的是在何处捕获,而不是是否捕获。如果您在一个中心位置执行此操作,即所谓的异常屏障,它位于调用堆栈的高层,那么这正是您应该执行的操作。如果你在代码的中间,在任意或更多的任意点上执行,这将是一个很糟糕的做法。

证明责任不应该在你身上,而是在你想要改变代码的工具上。任何合理的静态分析工具都会给出特定警告背后的基本原理,使您能够评估在特定情况下忽略该警告的影响。(大多数警告的存在是因为它们标记的代码经常有问题,而不是因为它总是有问题。)


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

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


所以对我来说,try{}块中的每个方法都应该抛出带有与该方法相关语义的已检查异常。递归地对所有这些方法都执行相同的操作,但我看不到任何工具足够聪明来为您执行此操作。

这是否位于任何合理堆栈的顶部,例如作为服务器中的顶级处理程序?如果是这样,捕获普通的
异常
(包括所有
运行时异常
值,但不包括
错误
)是有意义的,可以防止bug导致整个服务器停机。如果它不在顶层,它真的不应该捕获这些异常。哦,SQLException不是RuntimeException。是的,它是一个服务器应用程序,大多数捕获都是作为异常屏障工作的,但这通常不是在顶级实现的,而是在更深层的代码级别实现的。因此,我寻找一种好方法来将这些泛型分解成更具体的异常。拥有一个以上的异常屏障是错误的。您应该简单地删除这些处理程序,让异常向上传播。实际上没有处理
数组索引outofbounds
。您只需要记录完整的stacktrace,包括原因。@Marko:是的,但是如果您使用的代码有成千上万的代码行和对象,这可能是相当具有挑战性的返工。在我看来,这是正确的,但不幸的是,我没有处于建立新体系结构的状态,但是通过查看静态分析结果来修复已经存在的代码。还有一些情况下,原始开发人员只是捕获RuntimeException,因为他的。。。懒散之类的。通常情况下,在不更改API声明的限制中,这一点结合在一起。因此,我甚至无法将未检查的异常修改为有意义的已检查异常。是的,但这可能会导致代码更深入,并导致大量代码更改。最有问题的限制是:我不能更改API声明。因此,如果API元素已经存在,抛出检查过的异常通常不是一个选项。99%真实世界异常的唯一业务语义是“处理请求时出错。对不起”,而特定于域的异常的唯一一点是其业务语义。换言之,它99%毫无用处,只是一种负担。仅从业务角度来看,这是正确的。但是,该产品主要基于定制。因此,可靠且可理解的异常源不仅仅是一种好的方式。但是,如果有200名开发人员在使用同一个产品,那么要保持良好的源代码质量是很困难的。这就是为什么分手是个好主意