4

我最近一直在阅读许多关于异常的帖子,并且我有一个问题是否应该捕获未经检查的异常。我已经读过,如果您希望您的应用程序从错误中恢复,您可以使用检查异常。但是,如果您无法处理已检查的异常,则可以将其包装到另一个已检查的异常中,以便将其传递给另一层;例如你包装一个SqlException,或者你抛出一个未经检查的异常。但是,您应该捕获未经检查的异常吗?未经检查的异常是否是您不检查的理想编程错误?他们应该从您的应用程序中冒出来吗?

4

6 回答 6

9

是否应该捕获和处理未经检查的异常?

答案是这取决于:

  • 这取决于异常是什么。

  • 这取决于抛出异常的原因。是“预期的”吗?是因为错误、输入错误还是环境问题?或者是其他东西?

  • 这要看有没有好的恢复方法。这通常部分取决于先前的标准。

如果异常是意料之外的,异常的原因是不确定的,和/或如果你确实捕获了异常没有健全的恢复策略,那么通常最好让异常冒泡,并确保它得到报告/记录在顶层。

如果例外是Error,则一般规则是您不应尝试恢复。这包括StackOverflowError和(特别是)OutOfMemoryErrorError异常表示难以(或不可能)安全恢复的问题,最好的策略是允许或导致应用程序退出。


在顶层报告/记录是什么意思?你的意思是在 UI 层捕捉它并显示一个对话框、记录它等吗?

我的意思是应该将异常及其堆栈跟踪写入应用程序的日志文件,以便维护人员可以查看问题的证据。您是否还尝试向最终用户解释问题(以及如何做到这一点)是一个单独的问题。

“顶级”可能是“主”方法、子线程或可运行的“运行”方法……或未捕获的异常处理程序。基本上,如果异常没有被捕获,它最终会“冒泡”到任何地方。详细信息将取决于您的应用程序的架构。

于 2012-11-06T12:49:19.507 回答
5

如果您能以有意义的方式处理它以从问题中恢复,您应该捕获一个异常 - 已检查或未检查。如果您没有很好的处理方法,通常不应该捕获异常。

我已经看到太多代码通过执行e.printStackTrace()然后继续“处理”异常,就好像没有错一样。忽略这样的问题通常只会在以后导致其他问题。

于 2012-11-06T12:51:45.960 回答
4

没有什么可以阻止您捕获运行时异常。

现在的趋势是使用越来越多的运行时异常,而越来越少的受检异常。Spring、Hibernate 和最新的 Java EE 规范几乎完全使用运行时异常。这使业务代码更易于阅读且不那么繁琐。

为了显示错误消息,运行时异常通常根本不被捕获,或者只在调用堆栈的底部捕获发生。

于 2012-11-06T12:52:05.287 回答
1

检查异常的选择通常是:throws如果您对此无能为力,则只需将其添加catchcatch其中并在可行的情况下做一些事情,并且在你的代码中做一些事情的正确位置。

未经检查的异常有点棘手。在理想的世界中,它们应该指示编程/逻辑错误,并且非常像断言失败一样被处理,不会被捕获,尤其是不会被吞没。

在我看来,来自 Java 标准库或其他库的一些未经检查的异常确实应该是检查异常,但不是。在这些情况下,调用者应该承认这些异常可能会通过它们,即使它们没有通过catch它们。对于未检查的异常也可以是检查的异常,基本相同的规则:如果你想对它们做点什么就抓住它们,否则让它们冒泡。如果您正在创建一个库(即使它只是应用程序的内部),并且未经检查的异常确实应该稍后被捕获,那么您可能想要捕获并重新抛出它,并将其包装到库代码中的检查异常中.

一般来说,尽量避免抛出未经检查的异常。检查输入,所以你不需要catch,如果仍然抛出异常,那么这是一个错误,应该不被捕获。只有catch当它是唯一的或至少显然是最好的方式时,他们才会这样做。

公平地说,Java 库是在这个时代设计的语言,当时 IDE 还没有立即抱怨缺少 throws 子句并提供自动填充它们,因此通过减少开发人员的负担,使它们不受检查可能是合理的。但是使用现代工具,真的没有任何借口。

然后,正如其他答案中提到的那样,您不应该捕获未经检查的异常

于 2012-11-06T13:46:22.730 回答
1

Checked和Exception之间的基本区别在于Unchecked,您需要显式处理前者或将其传播到 中inheritance hierarchy,而后者则不需要。

另外,CheckedExceptionextend fromjava.lang.ExceptionUncheckedExceptionsextend fromjava.lang.RuntimeException不需要处理。请注意,RuntimeException它们本身是Exception.

鉴于以上所有信息,如果您愿意handleunchecked exception那就很好。它将正常工作,并且控件将转到相应的catch块。但你不应该这样做。除非,你真的需要它并且你有适当的方法来处理它们。

  • 例如: -你应该处理一个IllegalArgumentExceptionwhich 是一个Unchecked Exception.

  • 然后,您不应该处理以下错误: - StackOverflowError。因为,你不知道为什么会出现这个问题,以及什么是处理它的合适方法。所以,把它留给JVM。ErrorsUnchecked Exception你无法恢复的。

有关更多详细信息,请参阅以下链接:-

于 2012-11-06T12:50:45.853 回答
-1

你应该捕捉未经检查的异常吗?

是和否。取决于抛出什么异常。

未经检查的异常是否是您不检查的理想编程错误?

您可以编写一个catch块来捕获未经检查的异常,但这又取决于您是否应该这样做。如果你这样做了,那么一个 bug 可能会在很长一段时间内仍未解决,并且当它被发现时,它的大小也会发生变化。

他们应该从您的应用程序中冒出来吗?

如果它们发生,请尝试解决它们的原因(如果可能的话)。不要catch总是把它们当作硬性规定。

于 2012-11-06T12:51:27.550 回答