第72条:优先使用标准的异常
重用标准异常好处:
1.它使API更易于学习和使用,因为它与程序员已经熟悉的习惯用法一致
2.它们的可读性会更好,因为它们不会出现很多程序员不熟悉的异常
3.异常类越少,意味着内存占用就越小,装载这些类的时间开销也越少
不要直接重用Exception、RuntimeException、Throwable或者Error。对待这些类要像对象抽象类一样。你无法可靠的测试这些异常,因为它们是一个方法可能抛出的其他异常的超类。
如果某个异常能够满足你的需求,就不要犹豫,使用就是,不过一定要确保抛出的异常与该异常的文档中描述的条件一致。
第73条:抛出与抽象对应的异常
更高层的实现应该捕获底层的异常,同时抛出可以按照高层抽象进行解析的异常。
public E get(int index) {
ListIterator<E> i = listIterator(index);
try {
return i.next();
} catch (NoSuchElementException e) {
throw new IndexOutOfBoundsException("Index: " + index);
}
}
一种特殊的异常转译形式称为异常链,如果底层的异常对于调试导致高层异常的问题非常有帮助,使用异常链就很合适。
try {
... // Use lower-level abstraction to do our bidding
} catch (LowerLevelException cause) {
throw new HigherLevelException(cause);
}
大多数标准的异常都有支持链的构造器。对于没有支持链的异常,可以利用Throwable的initCause方法设置原因。
class HigherLevelException extends Exception {
HigherLevelException(Throwable cause) {
super(cause);
}
}
尽管异常转译与不加选择地从底层传递异常地做法相比有所改进,但是也不能滥用它。如有可能,处理来自低层异常地最好做法是,在调用低层方法之前确保它们会成功执行,从而避免它们抛出异常。有时候,可以在给低层传递参数之前,检查更高层方法参数地有效性,从而避免低层方法抛出异常。