Java异常

异常情形是指阻止当前方法或者作用域继续执行的问题。

为什么要使用异常

异常的处理机制可以确保我们程序的健壮性,提高系统可用率。

在没有异常机制的时候我们是这样处理的:通过函数的返回值来判断是否发生了异常(这个返回值通常是已经约定好了的),调用该函数的程序负责检查并且分析返回值。虽然可以解决异常问题,但是这样做存在几个缺陷:

  1. 容易混淆。异常约定返回值和真实返回值冲突。
  2. 代码可读性差。将异常处理代码和程序代码混淆在一起将会降低代码的可读性。
  3. 由调用函数来分析异常,这要求程序员对库函数有很深的了解。

使用异常机制它能够降低错误处理代码的复杂度,如果不使用异常,那么就必须检查特定的错误,并在程序中的许多地方去处理它,而如果使用异常,那就不必在方法调用处进行检查,因为异常机制将保证能够捕获这个错误,并且,只需在一个地方处理错误,即所谓的异常处理程序中。

异常类层次结构

Throwable有两个子类:Error(错误)和Exception(异常)。

Error:是程序无法处理的错误,表示运行程序中较严重的问题。这些异常发生时JVM一般会选择线程终止。
Exception:是程序本身可以处理的异常。又分为CheckedException(受检异常)和UncheckedException(非受检异常)。其中受检异常发生在编译阶段,必须使用try ... catch或者throws否则编译不通过。而非受检异常发生在运行期,具有不确定性,主要是由于程序的逻辑问题引起的。

异常处理机制

Java中的异常处理机制为:抛出异常和捕获异常。

抛出异常

当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。

捕获异常

在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。

运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。