美文网首页
第十章异常

第十章异常

作者: 后来丶_a24d | 来源:发表于2020-03-11 10:46 被阅读0次

目录

  • 仅在发生异常的条件下使用异常
  • 对可恢复条件使用已检查异常,对编程错误使用运行时异常
  • 避免不必要地使用检查异常
  • 赞成使用标准异常
  • 抛出合乎于抽象的异常
  • 文档化每个方法抛出的所有异常
  • 在详细信息中包含失败捕获信息
  • 争取保持失败原子性
  • 不要忽略异常

异常

仅在确有异常条件下使用异常

  • 一个设计良好的 API 不能迫使其客户端为一般的控制流程使用异常。只有在某些不可预知的条件下才能调用具有「状态依赖」方法的类,通常应该有一个单独的「状态测试」方法,表明是否适合调用「状态依赖」方法。例如,Iterator 接口具有「状态依赖」的 next 方法和对应的「状态测试」方法 hasNext。这使得传统 for 循环(在 for-each 循环内部也使用了 hasNext 方法)在集合上进行迭代成为标准习惯用。
  • 如果要在没有外部同步的情况下并发地访问对象,或者受制于外部条件的状态转换,则必须使用 Optional 或可识别的返回值,因为对象的状态可能在调用「状态测试」方法与「状态依赖」方法的间隔中发生变化。
  • 如果一个单独的「状态测试」方法重复「状态依赖」方法的工作,从性能问题考虑,可能要求使用 Optional 或可识别的返回值

对可恢复情况使用 checked 异常,对编程错误使用运行时异常

  • 把错误Error保留给 JVM 使用,以指示:资源不足、不可恢复故障或其他导致无法继续执行的条件。
    考虑到这种约定被大众认可,所以最好不要实现任何新的 Error 子类。
  • 因为 未checked 异常通常表示可恢复的条件,所以这类异常来说,设计能够提供信息的方法来帮助调用者从异常条件中恢复尤为重要。
    例如,假设当使用礼品卡购物由于资金不足而失败时,抛出一个 未checked 异常。该异常应提供一个访问器方法来查询差额。这将使调用者能够将金额传递给购物者。
  • 自定义的所有 unchecked 可抛出项都应该继承 RuntimeException,平常就是用的未受检异常
  • checked 异常必须捕获,未checked 异常没强制要求

避免不必要地使用 checked 异常

  • 如果一个方法抛出 checked 异常,调用它的代码必须在一个或多个 catch 块中处理它们;或者通过声明抛出,让它们向外传播。如果
    (1)正确使用 API 也不能防止异常情况
    (2)使用 API 的程序员在遇到异常时可以采取一些有用的操作
    那么这种负担是合理的。
  • 消除 checked 异常的最简单方法是返回所需结果类型的 Optional 对象(55)这种技术的缺点是,该方法不能返回任何详细说明其无法执行所需计算的附加信息

鼓励复用标准异常

  • 常见标准异常见参考文献

抛出能用抽象解释的异常

  • 异常转换:高层应该捕获低层异常,并确保抛出的异常可以用高层抽象解释
// 异常转换
try {
    ... // 使用较低层次的抽象来完成我们的任务
} catch (LowerLevelException e) {
    throw new HigherLevelException(...);
}
  • 链式异常:低层异常(作为原因)传递给高层异常,高层异常提供一个访问器方法(Throwable 的 getCause 方法)来检索低层异常
// Exception Chaining
try {
    ... // Use lower-level abstraction to do our bidding
}
catch (LowerLevelException cause) {
    throw new HigherLevelException(cause);
}

为每个方法记录会抛出的所有异常

  • rt

异常详细消息中应包含捕获失败的信息

  • 异常的详细消息应该包含导致异常的所有参数和字段的值
    不应包含密码、加密密钥等详细信息.
public IndexOutOfBoundsException(int lowerBound, int upperBound, int index) {
    // 生成捕获故障的详细信息
    super(String.format("Lower bound: %d, Upper bound: %d, Index: %d",lowerBound, upperBound, index));
    // 为编程访问保存故障信息s
    this.lowerBound = lowerBound;
    this.upperBound = upperBound;
    this.index = index;
}

尽力保证故障原子性

一般来说,一个失败的方法调用应该使对象处于调用之前的状态:

  1. 最简单的方法是设计不可变对象
  2. 而对于操作可变对象的方法,实现故障原子性的最常见方法是在执行操作之前检查参数的有效性
public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; // Eliminate obsolete reference
    return result;
}
- 上述例子中如果取消了初始大小检查,当该方法试图从空堆栈中弹出元素时,仍然会抛出异常。但是,这会使 size 字段处于不一致的(负值)状态,导致以后该对象的任何方法调用都会失败。
此外,pop 方法抛出的 ArrayIndexOutOfBoundsException 也不适于高层抽象解释
  1. 以对象的临时副本执行操作,并在操作完成后用临时副本替换对象的内容
  • 例如,一些排序函数在排序之前将其输入 list 复制到数组中,以降低访问排序内循环中的元素的成本。这样做是为了提高性能,但是作为一个额外的好处,它确保如果排序失败,输入 list 将保持不变
  1. 编写恢复代码,拦截在操作过程中发生的故障,并使对象回滚到操作开始之前的状

不要忽略异常

  • rt

参考文章

相关文章

  • 重构读书笔记-10_14-Replace_Error_Code_

    重构第十章 14.Replace Error Code With Exception(以异常取代错误码) 某个函数...

  • Pythone入门到实践-学习笔记-Day4

    第十章 文件和异常 一、文件 读取文件 用open()打开文件,用read()读取文件,用close()关闭文件,...

  • 重构读书笔记-10_15-Replace_Exception_w

    重构第十章 15.Replace Exception with Test(以测试取代异常)面对一个[调用者可以预先...

  • 第十章异常

    目录 仅在发生异常的条件下使用异常 对可恢复条件使用已检查异常,对编程错误使用运行时异常 避免不必要地使用检查异常...

  • 第十章,异常

    讨论异常,充分发挥异常的优点,可以提高程序的可读性、可靠性、可维护性 第六十九条 ,只针对异常的情况才使用异常1....

  • 第十章 异常处理

    异常概述 依赖于try catch finally throw throws五个关键字 Java把一场分为两种:C...

  • 2017-08-18

    第十章 信号 10.2 信号概念 产生信号的条件: 用户按下某些终端键时,引发终端产生的信号 硬件异常产生信号(除...

  • 阅读《Python编程从入门到实践》Day12

    第十章(一) 异常是Python创建的特殊对象,用于管理程序运行时出现的错误。模块json,能够保存用户数据,以免...

  • 第十章:文件和异常

    2018年10月25日 10.1 从文件中读取数据 要使用文本文件中的信息,首先需要将信息读取到内存中。为此可以一...

  • 第十章 Kotlin之异常

    异常类 如你所想,kotlin中所有的异常类跟java一样,都是Throwable类的后代。每个异常类都有消息,堆...

网友评论

      本文标题:第十章异常

      本文链接:https://www.haomeiwen.com/subject/djcqjhtx.html