69. 只针对异常的情况下才使用异常

异常应该只用于异常的情况下,他们永远不应该用于正常的程序控制流程,异常会导致额外的性能开销;

70. 对可恢复的情况使用受检异常,对编程错误使用运行时异常

异常类型
  • 受检异常
    使用场景:期望调用者能够合理的恢复程序运行
  • 运行时异常
    使用场景:处理编程错误,如NullPointException、ArrayIndexOutOfBoundsException
  • 错误
    使用场景:JVM保留使用
    对于可恢复的情况,要抛出受检异常;对于程序错误,就要抛出运行时异常。不确定是否可恢复,就跑出为受检异常。不要定义任何既不是受检异常也不是运行异常的抛出类型。要在受检异常上提供方法,以便协助程序恢复。

71. 避免不必要的使用受检异常

什么时候该抛出受检异常

  • 异常发生时调用方可恢复异常导致的失败行为
  • 异常发生时依据返回值无法提供足够的信息
  • 异常发生时调用方针对异常的发生需要处理额外的业务逻辑

72. 优先使用标准的异常

使用标准异常的好处
  • API易于使用和学习
  • 可读性更好
  • 异常类越少,内存占用越小

常用标准异常
  • IllegalArgumentException:非 null 的参数值不正确
  • llegalStateException:不适合方法调用的对象状态
  • NullPointerException:在禁止使用 null 的情况下参数值为 null
  • IndexOutOfBoundsExecption:下标参数值越界
  • ConcurrentModificationException:在禁止并发修改的情况下,检测到对象的并发修改
  • UnsupportedOperationException:对象不支持用户请求的方法

73. 抛出与抽象对应的异常

高层的实现应该适当的捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常,如:

  1. public E get(int index) {
  2. ListIterator<E> i = listIterator(index);
  3. try {
  4. return(i.next() );
  5. } catch (NoSuchElementException e) {
  6. throw new IndexOutOfBoundsException("Index: " + index);
  7. }
  8. }

74. 每个方法抛出的异常都需要创建文档

75. 在详细消息中包含失败捕获信息

76. 保持失败原子性

任何异常都应该让对象保持在调用该方法之前的状态

77. 不要忽略异常