异常

异常是程序在”编译”或者”执行”的过程中可能出现的问题。
异常一旦出现了,如果没有提前处理,程序退出JVM虚拟机而终止,开发中异常是需要提前处理的。
研究异常并且避免异常,然后提前处理异常,体现的是程序的安全, 健壮性!!!

Java 异常体系

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12568777/1622943746059-ba20fef3-05ea-4181-b9dc-1890bdf0c698.png#clientId=u0d4e4404-eb8e-4&from=paste&height=281&id=u3242082f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=562&originWidth=518&originalType=binary&ratio=2&size=22317&status=done&style=none&taskId=u22df928a-a3a3-4d1d-a9a7-fc73d6372e6&width=259)<br />Java中异常继承的根类是:Throwable;
  • Error:错误,这种类型出现后无法通过程序来处理,只能重启系统、优化项目;例如内存崩溃,JVM崩溃,开发者无法干预;
  • Exception:异常类,需要提前处理,使程序更加健壮;

异常分类:

  • 编译时异常:直接继承自 Exception 的异常类或者其子类,编译阶段就会报错,必须处理;
  • 运行时异常:继承自 RuntimeException 的异常类或者其子类,编译阶段不会报错,不进行处理的话,运行阶段会报错,影响程序健壮性,建议处理;

常见的运行时异常:

  • ArrayIndexOutOfBoundsException:数组索引越界异常;
  • NullPointerException:空指针异常;
  • ClassCastException:类型转换异常
  • NoSuchElementException:迭代器遍历没有此元素异常
  • ArithmeticException:数学操作异常
  • NumberFormatException:数字转换异常

    异常处理机制

  1. 可以在方法声明后 通过 throws 关键字向上抛出异常,交由上层处理;
  2. 可以在异常出现的地方 使用 try…catch… 代码块捕获并处理异常;

对于第一种向上抛出,如果上层没有进行捕获处理继续向上抛出到 JVM,属于默认的异常处理,JVM 会打印异常信息,然后终止程序

这种默认的处理方式不推荐,向上抛出异常后要在最外层使用第二种方式进行异常处理,避免程序由于异常中止。使用 try-catch 块处理异常,如果 catch 块中没有返回语句,程序往下正常执行。

finally 关键字

finally 一般用于代码执行完毕后资源的释放。配合 try…catch… 使用。

资源:实现了Closeable接口,自带close()关闭方法。

try:1次。
catch:0-N次 (如果有finally那么catch可以没有!!)
finally:0-1次

try {
    // 可能出现异常的代码
} catch(Exception e) {
    // 出现异常后的操作
    e.printStackTrace();
} finally {
    // 无论代码是出现异常还是正常执行,最终一定会执行这里的代码
}

对于 return 语句,如果 return 语句在 finally 块内,会覆盖之前的返回值。

面试题:try{}里有一个return语句,紧跟在try后的finally里的code会不会被执行,什么时候执行,return前执行还是return后执行。

会执行,在return之前