第十章异常

2020-03-11  本文已影响0人  后来丶_a24d

目录


异常

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

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

避免不必要地使用 checked 异常

鼓励复用标准异常

抛出能用抽象解释的异常

// 异常转换
try {
    ... // 使用较低层次的抽象来完成我们的任务
} catch (LowerLevelException e) {
    throw new HigherLevelException(...);
}
// Exception Chaining
try {
    ... // Use lower-level abstraction to do our bidding
}
catch (LowerLevelException cause) {
    throw new HigherLevelException(cause);
}

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

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

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. 以对象的临时副本执行操作,并在操作完成后用临时副本替换对象的内容
  1. 编写恢复代码,拦截在操作过程中发生的故障,并使对象回滚到操作开始之前的状

不要忽略异常


参考文章

上一篇 下一篇

猜你喜欢

热点阅读