5.1 Java异常处理机制
广义的异常是指应用程序在编译和运行期间出现的错误,在编译时出现的错误会被编译器指出,通过修改代码可以完成纠正,但在运行期间出现的错误将直接影响应用程序正常的运行,严格地讲异常是指应用程序在运行期间出现的错误。
5.1.1 异常的类型
在程序执行期间产生异常的情况有很多,例如非法的变量赋值、整数被0除、访问数组下标越界、要打开的文件不存在、在网络中数据传输被中断、计算机系统资源耗尽等。应用程序在运行期间发生错误将导致程序的正常执行流程被中断,异常可能造成程序终止运行或程序失去控制,更为严重的可能会造成计算机系统的瘫痪。
一般应用程序在运行期间可能会发生错误,错误大致有两类:一类是程序逻辑错误,逻辑错误一般是人为造成的,其修正需要人来处理;另一类是程序控制操作时可能发生的错误,这类错误大多数是与某种操作相关联的,即该操作可能会引发什么错误。程序控制操作时发生的错误通常是已知的,或是可预见的,有些错误是不可控制的(例如Java虚拟机产生错误),而有些错误是可控制的(例如整数被0除、访问数组下标越界、要打开的文件不存在等),而异常处理就是针对这类可控制的错误而言的。
5.1.2 异常处理机制
异常处理是指当程序运行时出现错误后该程序将如何处理。因为程序运行时发生异常总是在应用程序做操作处理期间,因此,在编写操作代码时,都会对每一个可能发生异常的操作代码做一些前期的评估,判断是否有潜在的可能要发生的异常,并在程序运行期间对所有可能出现的异常进行技术处理,确保应用程序安全、可靠地运行。
在传统的程序设计语言中,异常的处理一般是在设计应用程序主体逻辑的同时就要考虑可能出现的错误,并根据错误情况设计处理异常的逻辑,通常的做法是根据调用函数返回的错误代码(标志)了解函数执行是否出现错误,并做出相应的处理,而这种检测和处理错误的方式也会带来一些负面影响,例如程序代码的逻辑相对复杂(程序主体逻辑和错误处理代码混杂在一起)、错误信息不够准确等。
在面向对象的程序设计语言中,异常的处理被规范化了,它将各种不同的异常进行分类,并提供良好的异常处理接口,制定了异常处理机制。在编写程序代码时将处理异常代码与常规代码分离,当异常发生时,应用程序运行的流程就会发生改变,其程序的控制权将转移到异常处理代码部分,完成异常的处理,或者使应用程序安全地退出运行。面向对象程序设计的异常处理模式可以使编程人员从编写处理异常逻辑中解脱出来,但同时又可以有的放矢地对异常进行处理。
5.1.3 Java的异常处理
所有的面向对象程序设计语言都制定异常处理机制,Java语言同样也确定了异常处理机制。异常处理机制为复杂的应用程序提供了强有力的控制方式,使得程序代码更具有条理性和更便于维护,应用程序在各种环境下的运行更安全和可靠。
Java异常处理机制有两种模式:一种是捕获已知可能发生的异常并对异常进行处理,该模式是当检测到异常时将改变正常程序执行的流程,根据异常性质实施处理方式;另一种是异常的传播(抛出异常),即在应用程序操作中将可能发生的异常抛出去,抛给调用该操作的上一级方法,由上一级或更上一级方法处理或再抛出,直到最后抛向Java虚拟机而被虚拟机做终止程序运行等处理。概括而言,异常处理机制的程序处理部分由捕获异常、传播异常和人为处理异常三部分构成。
在Java体系中,每一个异常都被作为一个对象处理,有关异常的所有信息被包含在对象中,在Java的基础类库java.lang包中定义的java.lang.Throwable类被作为所有错误和异常类的父类,只有Throwable类或其子类创建的对象才能被Java的异常处理语句捕获,或者被异常处理语句抛出,因此,所有Java的类库中的异常类及人为自定义的异常类都应该是Throwable类的子类。
Java程序在运行期间可能出现两种类型的异常:一种是终止型,终止型比较严重,是不可恢复的,程序将被终止运行;另一种是继续型,继续型异常发生时,当被处理后,程序还可以返回到被异常中断处继续执行。定义在Java的基础类库java.lang包中、由Throwable类派生出两个标准的子类——java.lang.Error(错误)和java.lang.Exception(异常)类代表终止型和继续型两种类型的异常。Error错误类与Java虚拟机相关,当计算机系统崩溃、Java虚拟机出错、动态链接失败等错误发生时产生Error错误,Error类型的错误一般是致命的严重错误,不太可能被修正或恢复到错误之前的程序状态,因此,捕获和处理Error类型的错误基本上是无意义的,发生Error异常一般将导致应用程序中断。Exception异常类是可处理的异常,发生Exception异常不会导致应用程序中断执行,它可以通过捕获处理纠正错误或在Exception异常不影响程序正常执行的前提下将Exception异常抛出进行处理,典型的Exception异常有数组下标越界、整数被0除等。
Java应用程序在执行期间,当操作有异常出现时,Java虚拟机会自动创建一个包含异常信息的异常对象,并将它抛给应用程序。
【示例5-1】 产生异常的Java应用程序。
当程序执行到一个整数被0除的语句时,Java虚拟机抛出的异常信息如下:
Java虚拟机通过throw语句抛出一个ArithmeticException异常对象,ArithmeticException类是Exception类的一个子类,其抛出异常对象的语句为:
Java异常处理机制就是针对这些异常对象制定的捕获和传播(再抛出)方式的处理机制。