我最近一直在阅读许多关于异常的帖子,并且我有一个问题是否应该捕获未经检查的异常。我已经读过,如果您希望您的应用程序从错误中恢复,您可以使用检查异常。但是,如果您无法处理已检查的异常,则可以将其包装到另一个已检查的异常中,以便将其传递给另一层;例如你包装一个SqlException
,或者你抛出一个未经检查的异常。但是,您应该捕获未经检查的异常吗?未经检查的异常是否是您不检查的理想编程错误?他们应该从您的应用程序中冒出来吗?
6 回答
是否应该捕获和处理未经检查的异常?
答案是这取决于:
这取决于异常是什么。
这取决于抛出异常的原因。是“预期的”吗?是因为错误、输入错误还是环境问题?或者是其他东西?
这要看有没有好的恢复方法。这通常部分取决于先前的标准。
如果异常是意料之外的,异常的原因是不确定的,和/或如果你确实捕获了异常没有健全的恢复策略,那么通常最好让异常冒泡,并确保它得到报告/记录在顶层。
如果例外是Error
,则一般规则是您不应尝试恢复。这包括StackOverflowError
和(特别是)OutOfMemoryError
。Error
异常表示难以(或不可能)安全恢复的问题,最好的策略是允许或导致应用程序退出。
在顶层报告/记录是什么意思?你的意思是在 UI 层捕捉它并显示一个对话框、记录它等吗?
我的意思是应该将异常及其堆栈跟踪写入应用程序的日志文件,以便维护人员可以查看问题的证据。您是否还尝试向最终用户解释问题(以及如何做到这一点)是一个单独的问题。
“顶级”可能是“主”方法、子线程或可运行的“运行”方法……或未捕获的异常处理程序。基本上,如果异常没有被捕获,它最终会“冒泡”到任何地方。详细信息将取决于您的应用程序的架构。
如果您能以有意义的方式处理它以从问题中恢复,您应该捕获一个异常 - 已检查或未检查。如果您没有很好的处理方法,通常不应该捕获异常。
我已经看到太多代码通过执行e.printStackTrace()
然后继续“处理”异常,就好像没有错一样。忽略这样的问题通常只会在以后导致其他问题。
没有什么可以阻止您捕获运行时异常。
现在的趋势是使用越来越多的运行时异常,而越来越少的受检异常。Spring、Hibernate 和最新的 Java EE 规范几乎完全使用运行时异常。这使业务代码更易于阅读且不那么繁琐。
为了显示错误消息,运行时异常通常根本不被捕获,或者只在调用堆栈的底部捕获发生。
检查异常的选择通常是:throws
如果您对此无能为力,则只需将其添加catch
到catch
其中并在可行的情况下做一些事情,并且在你的代码中做一些事情的正确位置。
未经检查的异常有点棘手。在理想的世界中,它们应该指示编程/逻辑错误,并且非常像断言失败一样被处理,不会被捕获,尤其是不会被吞没。
在我看来,来自 Java 标准库或其他库的一些未经检查的异常确实应该是检查异常,但不是。在这些情况下,调用者应该承认这些异常可能会通过它们,即使它们没有通过catch
它们。对于未检查的异常也可以是检查的异常,基本相同的规则:如果你想对它们做点什么就抓住它们,否则让它们冒泡。如果您正在创建一个库(即使它只是应用程序的内部),并且未经检查的异常确实应该稍后被捕获,那么您可能想要捕获并重新抛出它,并将其包装到库代码中的检查异常中.
一般来说,尽量避免抛出未经检查的异常。检查输入,所以你不需要catch
,如果仍然抛出异常,那么这是一个错误,应该不被捕获。只有catch
当它是唯一的或至少显然是最好的方式时,他们才会这样做。
公平地说,Java 库是在这个时代设计的语言,当时 IDE 还没有立即抱怨缺少 throws 子句并提供自动填充它们,因此通过减少开发人员的负担,使它们不受检查可能是合理的。但是使用现代工具,真的没有任何借口。
然后,正如其他答案中提到的那样,您不应该捕获未经检查的异常。
Checked
和Exception之间的基本区别在于Unchecked
,您需要显式处理前者或将其传播到 中inheritance hierarchy
,而后者则不需要。
另外,CheckedException
extend fromjava.lang.Exception
和UncheckedExceptions
extend fromjava.lang.RuntimeException
不需要处理。请注意,RuntimeException
它们本身是Exception
.
鉴于以上所有信息,如果您愿意handle
,unchecked exception
那就很好。它将正常工作,并且控件将转到相应的catch
块。但你不应该这样做。除非,你真的需要它并且你有适当的方法来处理它们。
例如: -你应该处理一个
IllegalArgumentException
which 是一个Unchecked Exception
.然后,您不应该处理以下错误: -
StackOverflowError
。因为,你不知道为什么会出现这个问题,以及什么是处理它的合适方法。所以,把它留给JVM。Errors
是Unchecked Exception
你无法恢复的。
有关更多详细信息,请参阅以下链接:-
你应该捕捉未经检查的异常吗?
是和否。取决于抛出什么异常。
未经检查的异常是否是您不检查的理想编程错误?
您可以编写一个catch
块来捕获未经检查的异常,但这又取决于您是否应该这样做。如果你这样做了,那么一个 bug 可能会在很长一段时间内仍未解决,并且当它被发现时,它的大小也会发生变化。
他们应该从您的应用程序中冒出来吗?
如果它们发生,请尝试解决它们的原因(如果可能的话)。不要catch
总是把它们当作硬性规定。