在try catch中使用Throwable和Exception的区别

450

有时候,我会看到

try {

} catch(Throwable e) {

}

有时候

try {

} catch(Exception e) {

}

有什么区别?


3
相关链接:https://dev59.com/IXI95IYBdhLWcg3w1Bvo https://dev59.com/hHRB5IYBdhLWcg3w1Khe在Java中,Throwable是所有异常类和错误类的超类。Exception类是可以被抛出并需要捕获或声明的异常类型。与之相反,Error类通常表示虚拟机无法处理的严重问题。当你想要自定义异常时,应该从Exception类派生一个新的子类。如果你只是想抛出一个通用异常,可以使用Exception类或其子类。而Throwable类本身不应该直接使用,因为它过于广泛并且包含了错误类型。 - Jørn Schou-Rode
6个回答

356

通过捕获Throwable,它包括子类Error。你一般不应该这样做,除非在线程的最高“捕捉所有”级别处,你想记录或以其他方式处理可能出现的所有问题。这在框架类型的应用程序(例如应用服务器或测试框架)中更为典型,它可能正在运行未知代码,并且不应受到该代码出现的任何问题的影响,尽可能地保持稳定。


51
最好能在这里解释一下等级制度的情况。 - Xonatron
19
这个回答的背景是:Throwable类包含了Error和Exception两个子类,因此第一个try/catch包含第二个,但通常过于宽泛。 - T_T
4
它还包括了Throwable的用户自定义直接子类和Throwable实例本身。没有什么可以阻止你编写 throw new Throwable();,因此这是唯一真正捕获所有异常情况的方式。 - Antimony
6
尽管被接受,但这并没有回答问题,因为大部分答案描述的是捕获Exception和Throwable的最佳实践,而问题是关于它们之间的区别(即在何时使用哪个当我确实想要任意一个)。“它包括继承自Error的内容”是唯一指定的差异,这真的是一个全面的答案:什么是Error?为什么这很重要?还有其他的差异或最佳实践吗? - Oded Niv
@OdedNiv "什么是错误?为什么它包含在内很重要?" 你可以在另一个问题中提出这些问题。 - Kronen

269

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

Error是程序上无法恢复的,通常不需要捕获,除了用于记录目的(再次传递)之外。而Exception是可编程恢复的异常。它的子类RuntimeException表示编程错误,通常也不应该被捕获。


58
令人惊讶的是,即使在这个答案发布后的4年里,大多数“代码分析”工具仍然会将捕获 Throwable 作为一个严重的错误报告。捕获 Throwable 来进行日志记录是非常合理的。多年开发服务器的经验告诉我:1)即使出现Error,也会进行日志记录;2)除非进行日志记录,否则可能永远不会收到关于 OOM 的通知,这会让你想知道为什么服务器开始表现得“奇怪”。 - Bruno Grieder
4
“programmatically unrecoverable” 的确切含义是什么?它是否如此严重,以至于在捕获异常后我们基本上无法调用任何 Java 方法(记录日志等),而没有机会从 JVM 中获得不可预测的行为作为结果? - Alexander Abakumov
“它的子类RuntimeException表示编程错误”:我不确定是否同意这个说法。如果是真的,那么所有预期的异常都应该是可检查的异常。但是,如果我预计某些事情可能会失败,并且我的应用程序无法恢复,但我希望至少抛出一个有意义的异常,那该怎么办?在这种情况下使用可检查的异常似乎是无用的,并且会创建样板代码。 - Nom1fan

44

ThrowableExceptionError 的超类。通常情况下,我们应该捕获Exception子类的异常,这样就不会丢失根本原因。

只有在特殊情况下,假如您发现Java代码无法控制可能出现的错误时,才应该捕获ErrorThrowable异常。

我记得捕获Throwable来标记一个本地库未加载。


41

Throwable可以捕获几乎所有异常,包括默认情况下从现在已弃用的Thread.stop()方法抛出以停止线程的ThreadDeath。因此,通过捕获Throwable,您可以确保至少会经过catch块而不会离开try块,但您应该准备处理OutOfMemoryErrorInternalErrorStackOverflowError

捕获Throwable对于委托各种请求到外部代码但可能永远不会终止以保持服务活动的外部服务器循环非常有用。


40

9
一幅图片胜过千言万语。我认为这应该是被接受的答案。 - anticafe

4

我见过人们使用Throwable来捕获由于基础设施故障/不可用可能发生的一些错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接