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年出版,到现在已经将 ...
随机推荐
- Kafka 概念、单机搭建与使用
目录 Kafka 概念.单机搭建与使用 基本概念介绍 Topic Producer Consumer Kafka单机配置,一个Broker 环境: 配置zookeeper 配置Kafka 使用Kafk ...
- git命令详解( 七 )
此为git命令详解的第七篇 这章我们可以来逐渐揭开 git push.fetch 和 pull 的神秘面纱了.我们会逐个介绍这几个命令,它们在理念上是非常相似的. git push的参数 git ...
- 从小白到区块链工程师:第一阶段:Go语言的控制台输入和输出(3)
六,Print系列的函数输出 1:Println 打印换行.Print控制台打印,lnline 一行,打印数据后自动换一行显示.下面显示在控制台打印出不同的类型. 打印输出结果后,会自动换一行.打印结 ...
- Jenkins环境搭建(5)-与Jmeter完成参数化构建和构建前删除操作
此前介绍过几篇关于Jenkins配置相关的文章,今天再来说说参数化构建和构建前删除已有的报告.在实际测试过程中,是需要测试几套环境的,不使用参数化构建的话,构建脚本就比较麻烦了:自然,已生成的报告,不 ...
- MySQL5.7.23 VS MySQL5.6.21 分区表性能对比测试
为评估MySQL从5.6.21升级到5.7.23版本的性能,针对分区表的读写做了对比测试. [测试环境] 1. 两台HP380的物理机,配置一致,CPU:Intel(R) Xeon(R) CPU E5 ...
- python 数据结构之二叉树
二叉树关键在构建和遍历,python实现相对简单,我们在实现需要用到类,分别设置爱左右子树,根节点,然后从根进行遍历,进行判断,若为空进行树的构建,非空则返回到列表中即可,我在进行遍历时产生了一个错误 ...
- 在UnrealEngine中用Custom节点实现径向模糊
//input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //input UV 屏幕缓存的坐标坐标 //input Strength 力度 //inp ...
- CodeForce VKcup B
题目描述:给了n个单词和m,还有一堆YES和NO表示在序列1-m,2-(m+1),3-(m+2)......中是否存在重复的单词,没重复的是YES,有重复的是NO 题目链接:点我 如果是NO的话,就使 ...
- python 函数定义及调用
1.什么是函数? 在程序中,函数就是具备某一功能的工具,事先将工具准备好即函数的定义:遇到应用场景拿来就用即函数的调用:函数必须遵循先定义后调用的原则 2.为什么要用函数 不用函数的问题是: 程序冗长 ...
- Ural2110 : Remove or Maximize
设最大的数为$w$,若$n>k+\log w$,那么显然所有$1$都可以保留,否则现在$n\leq k+\log w$. 如果$w\leq 100000$,那么可以DP,设$f[i][j]$表示 ...