Effective Java 第三版——72. 同意使用标准异常

Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,因此JDK 最好下载 JDK 9以上的版本。java

Effective Java, Third Edition

72. 同意使用标准异常

专家级程序员与经验较少的程序员之间的一个区别是,专家力争并一般实现高度的代码重用。代码重用是一件好事,异常也不例外。Java类库提供了一组异常,涵盖了大多数API的异常抛出需求。git

重用标准异常有几个好处。其中最主要的是,它使你的API更容易学习和使用,由于它符合程序员已经熟悉的既定约定。其次,使用你的API的程序更容易阅读,由于它们不会由于不熟悉的异常而混乱。最后(也是最不重要的),更少的异常类意味着更小的内存占用和更少的加载类的时间。程序员

最经常使用的异常是IllegalArgumentException(条目 49)。 当调用者传入一个不合适的参数值时,一般抛出这个异常。 例如,若是调用者在表示某个操做重复次数的参数中传递了一个负数,则抛出此异常。github

另外一个经常使用的异常是IllegalStateException。 若是因为接收对象的状态而调用是非法的,则一般会抛出异常。 例如,若是调用者试图使用还没有正确初始化以前的对象时,则抛出这个异常。并发

能够说,每一个错误的方法调用均可以归结为非法参数或状态,可是还有一些异常一般用于某些类型的非法参数和状态。若是调用者在禁止null值的参数中传递null,那么按照惯例,抛出NullPointerException,而不是IllegalArgumentException异常。相似地,若是调用者将表示索引的参数中的超出范围的值传递给序列,则应该抛出IndexOutOfBoundsException,而不是IllegalArgumentException。app

另外一个可重用异常是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异常

相关文章
相关标签/搜索