在尝试捕获中使用Throwable和Exception之间的区别


Answers:


247

通过捕获,Throwable它包含了子类化的东西Error。通常,您不应该这样做,除非可能是在要记录的线程的最高“捕获所有”级别,或者绝对要处理可能出错的所有内容。这将是一个框架型应用程序(例如应用程序服务器或一个测试框架),它可以运行未知代码,不应受到影响比较典型的事情是去错代码,尽可能多地。


30
可能最好在这里解释一下层次结构。
Xonatron

11
此答案的上下文:Throwable将Error和Exception都包含为子类,因此第一次try / catch包括第二次尝试/捕获,但通常过于广泛。
Noel

2
它还包括用户定义的Throwable直接子类和Throwable本身的实例。没有什么可以阻止您写作throw new Throwable();,因此这是真正抓住一切的唯一途径。

3
尽管已被接受,但这并不能回答问题,因为大多数答案都描述了捕获Exception和Throwable的最佳实践,而问题是关于区别(例如何时使用时,我希望使用哪种)。“它包括错误的子类”是唯一指定的区别,它实际上是一个全面的答案:什么是错误?为什么包括它很重要?还有其他区别或最佳做法吗?
奥德·尼夫

@OdedNiv“什么是错误?为什么包含错误并不重要?” 您可以问另一个问题。
克朗

182

第一个捕获的所有子类Throwable(包括ExceptionError),第二个捕获的所有子类Exception

Error在任何情况下都无法以编程方式恢复,并且通常不会被捕获,除非出于日志目的(将其再次传递)。Exception可通过编程方式恢复。它的子类RuntimeException表示编程错误,通常也不会被捕获。


37
令人惊讶的是,在回答了4年后,大多数“代码分析”工具仍然将捕获可捕获性报告为严重错误。日志记录是捕获Throwable的非常正当的理由。多年的服务器开发经验告诉我,1)尽管会获得Error日志记录,并且仍然会记录日志; 2)除非有日志记录,否则您可能永远不会收到有关OOM发生的通知,这使您想知道为什么服务器开始表现为“滑稽”
Bruno Grieder

4
到底programmatically unrecoverable是什么意思?它是如此严重,以至于我们无法再捕获(记录等)该Java方法后再调用它,而没有机会从JVM中获得不可预测的行为?
亚历山大·阿巴库莫夫

Its subclass RuntimeException indicates a programming error:不确定我是否同意此声明。如果是这样,则意味着所有预期的异常都应检查为异常。如果我期望某些事情可能失败并且无法通过我的应用程序恢复,但我希望至少引发有意义的异常该怎么办?在这种情况下,使用检查异常似乎没有用,并会创建样板代码。
Nom1fan

22

Thowable甚至捕获ThreadDeath的所有东西,默认情况下会抛出该异常以停止现在不推荐使用的Thread.stop()方法中的线程。因此,通过捕获,Throwable您可以确保至少在没有通过catch块的情况下永远不会离开try块,但是您也应该准备处理OutOfMemoryErrorand InternalErrorStackOverflowError

捕获Throwable对于将各种请求委派给外部代码的外部服务器循环最有用,但它本身可能永远不会终止以保持服务的活动。


21

Throwable是超一流的Exception,以及Error。在正常情况下,我们应该始终捕获的子类Exception,以便根本原因不会丢失。

仅在特殊情况下,如果发现发生错误的可能性并且不受Java代码的控制,则应该使用ErrorThrowable

我记得捕获Throwable来标记未加载本机库。


0

我已经看到人们使用Throwable捕获由于基础架构故障/不可用而可能发生的一些错误。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.