69. 只针对异常的情况下才使用异常
异常应该只用于异常的情况下,他们永远不应该用于正常的程序控制流程,异常会导致额外的性能开销;
70. 对可恢复的情况使用受检异常,对编程错误使用运行时异常
异常类型
- 受检异常
使用场景:期望调用者能够合理的恢复程序运行 - 运行时异常
使用场景:处理编程错误,如NullPointException、ArrayIndexOutOfBoundsException - 错误
使用场景:JVM保留使用
对于可恢复的情况,要抛出受检异常;对于程序错误,就要抛出运行时异常。不确定是否可恢复,就跑出为受检异常。不要定义任何既不是受检异常也不是运行异常的抛出类型。要在受检异常上提供方法,以便协助程序恢复。
71. 避免不必要的使用受检异常
什么时候该抛出受检异常
- 异常发生时调用方可恢复异常导致的失败行为
- 异常发生时依据返回值无法提供足够的信息
- 异常发生时调用方针对异常的发生需要处理额外的业务逻辑
72. 优先使用标准的异常
使用标准异常的好处
- API易于使用和学习
- 可读性更好
- 异常类越少,内存占用越小
常用标准异常
- IllegalArgumentException:非 null 的参数值不正确
- llegalStateException:不适合方法调用的对象状态
- NullPointerException:在禁止使用 null 的情况下参数值为 null
- IndexOutOfBoundsExecption:下标参数值越界
- ConcurrentModificationException:在禁止并发修改的情况下,检测到对象的并发修改
- UnsupportedOperationException:对象不支持用户请求的方法
73. 抛出与抽象对应的异常
高层的实现应该适当的捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常,如:
public E get(int index) {
ListIterator<E> i = listIterator(index);
try {
return(i.next() );
} catch (NoSuchElementException e) {
throw new IndexOutOfBoundsException("Index: " + index);
}
}
74. 每个方法抛出的异常都需要创建文档
75. 在详细消息中包含失败捕获信息
76. 保持失败原子性
任何异常都应该让对象保持在调用该方法之前的状态