异常
程序运行期间不可避免会出现错误,可归为用户输入错误、设备错误、物理限制、代码错误等情况。当出现错误而使得某些操作无法完成时,程序应该具备以下能力:
-
返回到一种安全状态,让用户能执行其他命令
-
允许用户保存操作结果,妥善终止程序
异常处理(exception handing)的任务就是在错误发生时将控制权转移到合适的地方。Java 提供了异常处理机制,当某个方法不能正常完成它的任务时,可以通过另外一个路径退出方法,抛出(throw)一个封装了错误信息的对象,异常处理机制会搜索能够处理该异常状况的异常处理器(exception handler)。
一、异常分类
下图是 Java 异常层次结构的简化:
所有的异常都是从 Throwable 继承而来,在下一层分解为两个分支:Error 和 Exception,其中 Error 类层次结构描述了 Java 运行时系统的内部错误和资源耗尽错误,这种情况很少出现,不是我们必须关注的,一旦出现就只能尽量让程序安全终止。我们需要关注的是 Exception 层次结构,它又分解为两个分支:一个派生于 RuntimeException,另一个包含其他异常。
RuntimeException
如何界定?
-
RuntimeException(运行时异常):由程序错误导致的异常
-
其他异常:程序本身没有问题,像 I/O 错误这类问题导致的异常
派生于 RuntimeException 的异常包括但不限于下面几种情况:
-
ClassCastException / 类型转换错误
-
ArrayIndexOutOfBoundsException / 数组访问越界
-
NullPointerException / 访问 null 引用
其他异常则比如:
-
IOException / 试图在文件尾部之后读取数据
-
FileNotFoundException / 试图打开不存在的文件
-
ClassNotFoundException / 试图根据给定的(不正确)字符串查找 Class 对象
unchecked / checked
对于运行时异常,应该由编写程序的人解决,因为它只取决于代码本身。而其他异常还会受到不可预估的环境影响,比如一个文件可能在我检查它是否存在之前就已经被删除了。故此,把属于 Error 和 RuntimeException 的异常称为非受查异常(unchecked),其他异常则称为受查异常(checked),所谓受查,指的是编译器会检查是否为它们提供了对应的异常处理器。
二、抛出受查异常