Java错误和异常
在Java中,所有的异常都有一个共同的祖先Throwable
,它有两个重要的子类:Exception
(异常)和Error
(错误),二者都是Java异常处理的重要子类,各自都包含大量子类:
Error
Error
是程序无法处理的错误,表示代码运行时Java虚拟机出现的问题。例如,当Java虚拟机不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError
,而另外还有一个常见的错误是StackOverflowError
。这些错误是不可查的,也不应试图去捕获它,当这些错误发生时,Java虚拟机一般会选择终止。
Exception
Exception
异常是程序本身可以处理的异常,它有一个重要的子类RuntimeException
,表示JVM常用操作引发的异常。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常NullPointerException
、ArithmeticException
和ArrayIndexOutOfBoundException
。
运行时异常
Exception
这种异常分为运行时异常和非运行时异常(编译异常)两大类:
- 运行时异常:都是
RuntimeException
类及其子类异常,如NullPointerException
(空指针异常)、IndexOutOfBoundsException
(下标越界异常)等。这些异常是不检查异常,Java编译器不会检查它,即使没有用try-catch
语句捕获它,也没有用throws
子句声明抛出它,也会编译通过。 - 非运行时异常:是
RuntimeException
以外的异常,类型上都属于Exception
类及其子类。从程序语法角度讲是必须进行处理的异常(try-catch
捕捉或者方法上声明throws
抛出),如果不处理,程序就不能编译通过,如IOException
、SQLException
等。
处理异常机制
在Java应用程序中,异常处理机制为:抛出异常,捕捉异常。
- 抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息,运行时系统负责寻找处置异常的代码并执行。
- 捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止,同时意味着Java程序的终止。
一旦某个catch
捕获到匹配的异常类型,将进入异常处理代码。一经处理结束,就意味着整个try-catch
语句结束,其他的catch
子句不再有匹配和捕获异常类型的机会。