Tips
书中的源代码地址:
注意, 书中的有些代码里方法是基于 Java 9 API 中的, 所以 JDK 最好下载 JDK 9 以上的版本.
70. 对可恢复条件使用已检查异常, 对编程错误使用运行时异常
Java 提供了三种可抛出异常对象: 已检查异常 ( checked exceptions), 运行时异常(runtime exceptions) 和虚拟机错误(errors). 程序员们对什么时候使用每种抛出的异常比较困惑. 虽然决策并不总是明确的, 但是有一些通用规则可以提供有力的指导.
决定是否使用已检查异常或未检查异常的基本规则是: 对于可以合理地预期调用者将从中恢复的条件, 使用已检查异常. 通过抛出一个已检查的异常, 可以强制调用者在 catch 子句中处理异常, 或者将其传播出去. 因此, 声明要抛出方法的每个已检查异常都有力地向 API 用户表明, 关联的条件是调用该方法的一个可能的结果.
通过向用户提供已检查异常, API 设计器提供了从异常条件中恢复的要求. 用户可以通过捕获异常并忽略异常来无视这个要求, 但这通常不是一个好主意(条目 77).
有两种未检查的可抛出的异常: 运行时异常和虚拟机错误. 它们在行为上是一样的: 都是可抛出的, 通常不应该被捕获. 如果程序抛出未检查的异常或错误, 通常情况下是无法恢复的, 继续执行的话弊大于利. 如果程序没有捕捉到这样的可抛出的异常, 会导致当前线程挂起或停止, 并发出适当的错误消息.
使用运行时异常来指出编程错误. 绝大多数运行时异常表示违反了先决条件(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). 可抛出的类很少指定其字符串表示的细节, 因此字符串表示可能因实现而异, 也可能因发布而异. 因此, 解析异常的字符串表示的代码可能是不可移植且脆弱的.
因为检查异常通常表示可恢复的异常条件, 所以对它们来说, 提供信息的方法来帮助调用者从异常条件中恢复尤为重要. 例如, 假设当使用礼品卡购物的尝试由于资金不足而失败时, 抛出一个已检查的异常. 异常应该提供一个访问器方法来查询差额的数量. 这会使调用者能够将金额传递给购物者. 有关此主题的更多信息, 请参见条目 75.
总而言之, 为可恢复的异常条件抛出已检查异常, 为编程错误抛出未检查异常. 当有疑虑不确定时, 抛出未检查的异常. 不要定义任何既不是已检查异常也不是运行时异常的可抛出异常. 提供已检查异常的方法, 用来帮助恢复.
来源: https://www.cnblogs.com/IcanFixIt/p/10614545.html