Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常

Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,因此JDK 最好下载 JDK 9以上的版本。java

Effective Java, Third Edition

70. 对可恢复条件使用已检查异常,对编程错误使用运行时异常

Java提供了三种可抛出异常对象:已检查异常( checked exceptions)、运行时异常(runtime exceptions)和虚拟机错误(errors)。程序员们对何时使用每种抛出的异常比较困惑。虽然决策并不老是明确的,可是有一些通用规则能够提供有力的指导。git

决定是否使用已检查异常或未检查异常的基本规则是:对于能够合理地预期调用者将从中恢复的条件,使用已检查异常。经过抛出一个已检查的异常,能够强制调用者在catch子句中处理异常,或者将其传播出去。所以,声明要抛出方法的每一个已检查异常都有力地向API用户代表,关联的条件是调用该方法的一个可能的结果。程序员

经过向用户提供已检查异常,API设计器提供了从异常条件中恢复的要求。用户能够经过捕获异常并忽略异常来无视这个要求,但这一般不是一个好主意(条目 77)。github

有两种未检查的可抛出的异常:运行时异常和虚拟机错误。它们在行为上是同样的:都是可抛出的,一般不该该被捕获。若是程序抛出未检查的异常或错误,一般状况下是没法恢复的,继续执行的话弊大于利。若是程序没有捕捉到这样的可抛出的异常,会致使当前线程挂起或中止,并发出适当的错误消息。编程

使用运行时异常来指出编程错误。 绝大多数运行时异常表示违反了先决条件(precondition violation)。 违反先决条件的缘由仅仅是客户端API没法遵照API规范创建的约定。 例如,数组访问的约定指定数组索引必须介于0和数组长度减去1之间)。 ArrayIndexOutOfBoundsException异常指出违反了此先决条件。数组

这个建议的一个问题是,你并不老是清楚是在处理可恢复的异常仍是编程错误。例如,考虑资源耗尽的状况,这多是由编程错误(如分配一个不合理的大数组)或真正的资源短缺形成的。若是资源枯竭是因为临时短缺或需求临时增长形成的,这种状况极可能是能够恢复的。对于API设计人员来讲,判断给定的资源耗尽实例是否容许恢复是一个问题。若是你认为某个条件可能容许恢复,请使用已检查的异常;若是不能,则使用运行时异常。若是不清楚是否能够恢复,最好使用未检查的异常,缘由将在条目 71中讨论。并发

虽然Java语言规范没有要求,但有一个强烈的约定,即保留错误(errors)以供JVM使用,以指示资源缺陷,不变性失败(invariant failures),以及其余没法继续执行的条件。 鉴于几乎广泛接受这种约定,最好不要实现任何新的Error子类。 所以,实现全部未经检查的可抛出异常应该是RuntimeException的子类(直接或间接子类)。 不只不该该定义Error子类,并且除了AssertionError以外,也不该该抛出它们。线程

能够定义一个可抛出的异常,不是Exception、RuntimeException或Error的子类。JLS不直接处理这些可抛出类,而是隐式地指定它们做为普通的检查异常(它们是Exception的子类,但不是RuntimeException)。那么,何时应该使用这样的可抛出异常?总之,永远不会。与普通的检查异常相比,它们没有任何好处,只会让API的使用者感到困惑。设计

API设计者常常忘记异常是也是彻底成熟的对象,能够在其上定义任意方法。此类方法的主要用途是提供捕获异常的代码,其中包含有关致使抛出异常的条件的其余信息。 在没有这样的方法的状况下,已知程序员解析异常的字符串表示以发现附加信息。 这是很是糟糕的作法(条目 12)。 可抛出的类不多指定其字符串表示的细节,所以字符串表示可能因实现而异,也可能因发布而异。 所以,解析异常的字符串表示的代码多是不可移植且脆弱的。code

由于检查异常一般表示可恢复的异常条件,因此对它们来讲,提供信息的方法来帮助调用者从异常条件中恢复尤其重要。例如,假设当使用礼品卡购物的尝试因为资金不足而失败时,抛出一个已检查的异常。异常应该提供一个访问器方法来查询差额的数量。这会使调用者可以将金额传递给购物者。有关此主题的更多信息,请参见条目 75。

总而言之,为可恢复的异常条件抛出已检查异常,为编程错误抛出未检查异常。当有疑虑不肯定时,抛出未检查的异常。不要定义任何既不是已检查异常也不是运行时异常的可抛出异常。提供已检查异常的方法,用来帮助恢复。

相关文章
相关标签/搜索