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. 赞成使用标准异常的更多相关文章

  1. Effective Java 第三版——44. 优先使用标准的函数式接口

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. Effective Java 第三版——69. 仅在发生异常的条件下使用异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  3. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  4. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  5. Effective Java 第三版——49. 检查参数有效性

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——7. 消除过期的对象引用

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——9. 使用try-with-resources语句替代try-finally语句

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. Dicom文件转mhd,raw文件格式

    最近在整理与回顾刚加入实验室所学的相关知识,那会主要是对DICOM这个医疗图像进行相应的研究,之前有一篇博客已经讲述了一些有关DICOM的基本知识,今天这篇博客就让我们了解一下如何将Dicom文件转为 ...

  2. Xamarin Essentials教程打开文件

    Xamarin Essentials教程打开文件 FileSystem类的OpenAppPackageFileAsync()方法可以用来打开App包中特定的文件,其语法形式如下: public sta ...

  3. luogu P2962 [USACO09NOV]灯Lights 高斯消元

    目录 题目链接 题解 题目链接 luogu P2962 [USACO09NOV]灯Lights 题解 可以折半搜索 map合并 复杂度 2^(n / 2)*logn 高斯消元后得到每个点的翻转状态 爆 ...

  4. BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)

    BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...

  5. Codeforces.1082E.Increasing Frequency(思路)

    题目链接 \(Description\) 给定\(n\)个数.你可以选择一段区间将它们都加上或减去任意一个数.求最终序列中最多能有多少个数等于给定的\(C\). \(n\leq5\times10^5\ ...

  6. tomcat环境变量详细配置步骤

    这篇文章主要为大家详细介绍了tomcat环境变量配置步骤,包括JDK环境变量配置,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了tomcat环境变量的配置教程,供大家参考,具体内容如下 1.=== ...

  7. LeetCode(509. 斐波那数)

    问题描述: 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列.该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就是: F(0) = 0, F(1) = 1 F(N) ...

  8. 潭州课堂25班:Ph201805201 爬虫高级 第十课 Scrapy-redis分布 (课堂笔记)

    利用 redis 数据库,做 request 队列,去重,多台数据共享, scrapy 调度 基于文件每户,默认只能在单机运行, scrapy-redis 默认把数据放到 redis 中,实现数据共享 ...

  9. nodejs EventEmitter 发送消息

    var util = require('util'); var evem = require('events').EventEmitter; function myem(){ evem.call(th ...

  10. 考前停课集训 Day2 非

    因为太长了 所以一天一天分开发 Day2 昨天晚上没开黑车 没脱衣服就睡了 可能是我难受了…… 新的一天. 早上好. 我没去晨跑,早上先和团长集合了,没看见rkbudlo来 于是就先吃饭了 去机房的时 ...