try/catch/finally

  • 如果没有try,异常将击穿所有的栈帧
  • catch可以将⼀个异常抓住
  • finally执⾏清理⼯作
  • JDK7+:try-with-resources
    • 实现了autoClose接口

throw/throws

  • throw抛出⼀个异常
    • 会终止当前的流程
    • 击穿所有栈帧,直到catch
  • throws只是⼀个声明
    • 声明在方法上,声明这个方法可能会抛出什么异常
    • 调用这个方法时必须try-catch

Java的异常体系

  • Throwable - 所有错误和异常的父类(感染:任何调用它的方法外层都要加try-catch或者throws)
    • Exception - checked exception 受检异常-代表意料之中的异常(感染)
    • RuntimeException - 运行时异常-意料之外的异常(不感染)
    • Error 错误 - 不可恢复的异常(不感染)
  • catch的级联与合并

    1. try {
    2. // ...
    3. //可以用 | 而不是多个catch
    4. } catch (NullPoinerException | IllegalAccessException e) {
    5. // ...
    6. }
  • 程序意料之中的异常需要用checked exception,让调用者去处理它

Throwable

  • 栈轨迹 Stacktrace:排查问题最重要的信息,没有之一
  • 异常链 Caused by

异常的抛出原则

1. 能用if/else处理的,就不要用异常

  • 无法保证catch到的异常一定是你预期的,可能错误地catch到更深处的异常
  • 相比if判断,异常的创建是非常昂贵的操作

    2. 尽早抛出异常

    3. 异常要准确,带有详细信息

    4. 抛出异常也比悄悄地执行错误的逻辑强得多

  • 自己不能处理的异常就抛出来

  • 除非万不得已,不要忽略异常,执行错误的逻辑