• 历史
    • UNIVAC I
      • 1950
      • 溢出时中断(interrupt)跳转到000
    • COBOL
      • 1959
      • 两种类型错误,用两关键字处理
    • I
      • 1964
      • 先定义出错处理代码。编程时引入on语句goto到处理代码, 不检查返回值
      • 可定义新错误类型, 可用signal condition主动出错
    • John Goodenough
      • 1975
      • 程序员可能忘处理异常、在不正确位置处理、处理不正确类型异常
      • 应该声明可能抛出的异常、将可能出错结构括起来的语句结构
    • CLU
      • 1975
      • begin … end 后 except 错误类型, 再写错误处理语句
    • C++
      • 1983, 1984-1989多次讨论
      • try{}catch{}, throw抛异常(没用raise和signal, 因为它们已经使用了)
    • Windows NT 3.1
      • 1993
      • 使用finally
    • Java
      • 1995
      • 引入finally
    • D语言
      • 2001
      • 作用域守护取代finally, 写在初始化语句后面scope(exit) unlock(m)
  • 方式
    • 返回值
      • 会遗漏错误,可读性下降
    • 异常处理
      • 函数多出口
      • 必执行代码
        • 成对操作无遗漏,不使用goto执行同段代码
        • finally
          • Java, Ruby, Python
        • 析构函数
  • 何时使用异常
    • 有不同的规则。缺少参数,js不抛异常。数据越界,JS返回undefined, ruby返回nil
    • 出错立刻抛异常
      • 错误优先(fail first), 早发现问题
  • 异常传递
    • 一层层函数向上传递,都无处理时程序异常退出
    • 上层函数不了解下层异常细节
    • 不了解下层调用不能捕获全部异常
      • Java用检查型异常解决, 但很麻烦