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年出版,到现在已经将 ...
随机推荐
- Airtest基本使用
前段时间在博客中见到airtest的介绍,自己并实践了一番,用起来的确很方便,所以今天就来分享下. Airtest简介 Airtest是网易出品的一款基于图像识别和poco控件识别的一款UI自动化测试 ...
- How to check for null/empty/whitespace values with a single test?
SELECT column_name FROM table_name WHERE TRIM(column_name) IS NULL
- EF Core中的多对多映射如何实现?
EF 6.X中的多对多映射是直接使用HasMany-HasMany来做的.但是到了EF Core中,不再直接支持这种方式了,可以是可以使用,但是不推荐,具体使用可以参考<你必须掌握的Entity ...
- 英语口语练习系列-C32-建筑-述说时间-暮秋独游曲江
词汇-building(建筑) entertainment Olympic-sized swimming pool tennis court basketball field football pit ...
- php数组和对象转换函数
/** * 数组 转 对象 * * @param array $arr 数组 * @return object */ function array_to_object($arr) { ...
- js计算本地时间
获取时间戳: 方法一 var dateTime = new Date();//获取本地时间 var nowTime = dateTime.getTime();//获取本地毫秒,即当前时间 var en ...
- SuperWebSocket与Cocos2dx通信时执行不了命令的问题
要修改WebSocketSession.cs 中的方法 string IWebSocketSession.GetAvailableSubProtocol(string protocol) { if ( ...
- 命令和python模式转换
安装完paython成功之后,就必须了解一下:命令模式和python交互模式 1.我们输入 cmd 之后进入的运行环境就是命令模式 2.在命令模式下输入 python,看到>>> ...
- HTTP中的重定向和请求转发的区别(转)
一.调用方式 我们知道,在servlet中调用转发.重定向的语句如下: request.getRequestDispatcher("new.jsp").forward(reques ...
- 多个ip以逗号分隔
/^(((?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9 ...