Effective Java 第三版——72. 赞成使用标准异常
Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。

72. 赞成使用标准异常
专家级程序员与经验较少的程序员之间的一个区别是,专家力争并通常实现高度的代码重用。代码重用是一件好事,异常也不例外。Java类库提供了一组异常,涵盖了大多数API的异常抛出需求。
重用标准异常有几个好处。其中最主要的是,它使你的API更容易学习和使用,因为它符合程序员已经熟悉的既定约定。其次,使用你的API的程序更容易阅读,因为它们不会因为不熟悉的异常而混乱。最后(也是最不重要的),更少的异常类意味着更小的内存占用和更少的加载类的时间。
最常用的异常是IllegalArgumentException(条目 49)。 当调用者传入一个不合适的参数值时,通常抛出这个异常。 例如,如果调用者在表示某个操作重复次数的参数中传递了一个负数,则抛出此异常。
另一个常用的异常是IllegalStateException。 如果由于接收对象的状态而调用是非法的,则通常会抛出异常。 例如,如果调用者试图使用尚未正确初始化之前的对象时,则抛出这个异常。
可以说,每个错误的方法调用都可以归结为非法参数或状态,但是还有一些异常通常用于某些类型的非法参数和状态。如果调用者在禁止null值的参数中传递null,那么按照惯例,抛出NullPointerException,而不是IllegalArgumentException异常。类似地,如果调用者将表示索引的参数中的超出范围的值传递给序列,则应该抛出IndexOutOfBoundsException,而不是IllegalArgumentException。
另一个可重用异常是ConcurrentModificationException。如果一个对象被设计为由单个线程使用(或与外部同步),并且检测到它正在被并发地修改,则应该抛出该对象。这个异常最多是一个提示,因为无法可靠地检测并发修改。
最后一个需要注意的标准异常是UnsupportedOperationException。如果对象不支持尝试的操作,则抛出此异常。它很少使用,因为大多数对象都支持它们的所有方法。此异常用于无法实现由其实现的接口定义的一个或多个Optional操作的类。例如,如果有人试图从仅支持追加(append-only )的列表中删除元素,则将抛出此异常。
不要直接重用Exception、RuntimeException、Throwable或Error。将这些类视为抽象类。你不能对这些异常进行可靠的测试,因为它们是方法可能抛出的其他异常的父类。
此表总结了最常见的重用异常:
| 异常 | 使用场景 |
|---|---|
| IllegalArgumentException | 不合适的非null参数值 |
| IllegalStateException | 方法调用状态不适合的对象 |
| NullPointerException | 再禁止使用null的情况下参数值为null |
| IndexOutOfBoundsException | 索引参数值越界 |
| ConcurrentModificationException | 在禁止并发修改对象的地方检测到该对象被并发修改 |
| UnsupportedOperationException | 对象不支持方法 |
虽然到目前为止,这些是最常见的重用异常,但是在环境允许的情况下也可以重用其他异常。例如,如果正在实现诸如复数或有理数之类的算术对象,那么重用ArithmeticException和NumberFormatException是合适的。如果一个异常符合你的需要,那么继续使用它,但前提是抛出它的条件与异常文档描述一致:重用必须基于文档化的语义,而不仅仅是基于名称。另外,如果想添加更多的细节,可以随意子类化标准异常(条目 75),但是请记住异常是可序列化的(第12章)。这本身就是,如果没有充分理由,不要编写自己的异常类的原因。
选择重用哪个异常可能比较棘手,因为上面表格中的“使用场景”似乎并不相互排斥。考虑表示一副纸牌的对象的情况,假设有表示发一手牌的方法,该方法参数是一手牌的纸牌数量。如果调用者传递的值大于整副牌中剩余的牌的数量,则可以将其解释为IllegalArgumentException (handSize参数值过大),或者是IllegalStateException(纸牌中包含的牌太少)。在这种情况下,规则是,如果没有参数值,则抛出IllegalArgumentException,否则抛出IllegalArgumentException异常。
Effective Java 第三版——72. 赞成使用标准异常的更多相关文章
- Effective Java 第三版——44. 优先使用标准的函数式接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——69. 仅在发生异常的条件下使用异常
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
- 《Effective Java 第三版》新条目介绍
版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...
- Effective Java 第三版——49. 检查参数有效性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 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年出版,到现在已经将 ...
- Effective Java 第三版——9. 使用try-with-resources语句替代try-finally语句
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- Dicom文件转mhd,raw文件格式
最近在整理与回顾刚加入实验室所学的相关知识,那会主要是对DICOM这个医疗图像进行相应的研究,之前有一篇博客已经讲述了一些有关DICOM的基本知识,今天这篇博客就让我们了解一下如何将Dicom文件转为 ...
- Xamarin Essentials教程打开文件
Xamarin Essentials教程打开文件 FileSystem类的OpenAppPackageFileAsync()方法可以用来打开App包中特定的文件,其语法形式如下: public sta ...
- luogu P2962 [USACO09NOV]灯Lights 高斯消元
目录 题目链接 题解 题目链接 luogu P2962 [USACO09NOV]灯Lights 题解 可以折半搜索 map合并 复杂度 2^(n / 2)*logn 高斯消元后得到每个点的翻转状态 爆 ...
- BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)
BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...
- Codeforces.1082E.Increasing Frequency(思路)
题目链接 \(Description\) 给定\(n\)个数.你可以选择一段区间将它们都加上或减去任意一个数.求最终序列中最多能有多少个数等于给定的\(C\). \(n\leq5\times10^5\ ...
- tomcat环境变量详细配置步骤
这篇文章主要为大家详细介绍了tomcat环境变量配置步骤,包括JDK环境变量配置,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了tomcat环境变量的配置教程,供大家参考,具体内容如下 1.=== ...
- LeetCode(509. 斐波那数)
问题描述: 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列.该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就是: F(0) = 0, F(1) = 1 F(N) ...
- 潭州课堂25班:Ph201805201 爬虫高级 第十课 Scrapy-redis分布 (课堂笔记)
利用 redis 数据库,做 request 队列,去重,多台数据共享, scrapy 调度 基于文件每户,默认只能在单机运行, scrapy-redis 默认把数据放到 redis 中,实现数据共享 ...
- nodejs EventEmitter 发送消息
var util = require('util'); var evem = require('events').EventEmitter; function myem(){ evem.call(th ...
- 考前停课集训 Day2 非
因为太长了 所以一天一天分开发 Day2 昨天晚上没开黑车 没脱衣服就睡了 可能是我难受了…… 新的一天. 早上好. 我没去晨跑,早上先和团长集合了,没看见rkbudlo来 于是就先吃饭了 去机房的时 ...