Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常
Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于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。
总而言之,为可恢复的异常条件抛出已检查异常,为编程错误抛出未检查异常。当有疑虑不确定时,抛出未检查的异常。不要定义任何既不是已检查异常也不是运行时异常的可抛出异常。提供已检查异常的方法,用来帮助恢复。
Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常的更多相关文章
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
- 《Effective Java 第三版》新条目介绍
版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...
- Effective Java 第三版——26. 不要使用原始类型
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- java异常继承何类,运行时异常与一般异常的区别
一.基本概念 Throwable是所有异常的根,java.lang.ThrowableError是错误,java.lang.ErrorException是异常,java.lang.Exception ...
- Effective Java 第三版——34. 使用枚举类型替代整型常量
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- effective java(第三版)---读书笔记
第一章 引言 < Effective Java>这本书并不厚,而且并不适合初学者,适合有一定的工作经验的java攻城狮.这本书不是百科全书式的JAVA 手册,而是试图在讲述如何正确.高效地 ...
- Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——7. 消除过期的对象引用
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- POJ 2631 Roads in the North (模板题)(树的直径)
<题目链接> 题目大意:求一颗带权树上任意两点的最远路径长度. 解题分析: 裸的树的直径,可由树形DP和DFS.BFS求解,下面介绍的是BFS解法. 在树上跑两遍BFS即可,第一遍BFS以 ...
- Springboot集成ES启动报错
报错内容 None of the configured nodes are available elasticsearch.yml配置 cluster.name: fans node.name: no ...
- 服务注册与发现---eureka
eureka简介:云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移. 话不多说直接上代码 首先新建一个springcloud eurekaserver项目. ...
- 【持久化框架】Mybatis与Hibernate的详细对比(转发)
前言 这篇博文我们重点分析一下Mybatis与Hibernate的区别,当然在前面的博文中我们已经深入的研究了Mybatis和Hibernate的原理. Mybatis [持久化框架]Mybatis简 ...
- HDU.5394.Trie in Tina Town(回文树)
题目链接 \(Description\) 给定一棵\(Trie\).求\(Trie\)上所有回文串 长度乘以出现次数 的和.这里的回文串只能是从上到下的一条链. 节点数\(n\leq 2\times ...
- IDEA中的常用设置
ps:对于开发工具,不同的开发人员有不同的设置喜好,这里介绍的是我个人的配置,不喜勿喷. Appearance:个人喜欢全黑主题,雅黑字体 背景图片, 效果如下,编写代码的时候有个自己喜欢的背景图片, ...
- 2159 ACM 杭电 杀怪 二维费用的背包+完全背包问题
题意:已知经验值,保留的忍耐度,怪的种数和最多的杀怪数.求进入下一级的最优方案. 思路:用二维费用的背包+完全背包问题 (顺序循环)方法求解 什么是二维费用的背包问题? 问题: 二维费用的背包问题是指 ...
- 错误解决记录------------mysql连接本地数据库显示"can't get hostname for your address"
mysql连接本地数据库遇到 can't get hostname for your address 不明原因的本地mysql数据库连接不上,总是显示can't get hostname for yo ...
- 直接存储器存取(Direct Memory Access,DMA)详细讲解
一.理论理解部分. 1.直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输. 2.无须CPU干预,数据可以通过DMA快速移动,这就节省了CPU的资源来做其他操作. ...
- CentOs中玩docker
1.启动: systemctl start docker.service 2.停止: systemctl stop docker 3.从usts上拉取仓库 编辑文件 vi /etc/docker/da ...