5.3 Java异常的抛出
在Java面向对象编程体系中,所有实现操作的程序代码都被安排在方法体中。有些操作代码有可能会产生异常,当没有计划在该方法体中处理异常时,可将异常对象抛出到方法体外,由调用该方法的上一级方法进行捕获或者接力抛出等处理,直到将异常对象抛向Java虚拟机,由Java虚拟机来处理。
5.3.1 从方法体中抛出异常对象
从方法体中抛出异常对象是使用Java关键字throws实现的,throws可以抛出多个异常对象。throws关键字的使用语法格式为:
抛出异常对象的语句说明:在方法体SomeMethod中实现操作的程序代码可能会产生这样OneException或那样AnotherException等类型的异常,通过throws将它们都抛出去,让调用someMethod()方法的上一级方法进行异常处理。另外,不能通过更改方法抛出的异常类型实现方法的重载。
【示例5-7】 使用throws抛出异常对象的程序。其程序代码为:
上述程序在Division()方法中并没有涉及异常处理的程序代码,但是其功能是实现两个整数相除的操作,可能会出现除数为0的情况,将会产生异常,因此,Division()方法将可能产生的ArithmeticException类型的异常对象抛出,交给调用Division()方法的上一级main()方法中处理,在main()方法中通过try-catch语句捕获和处理在Division()方法中出现的异常,如果在main()方法中不对异常做任何处理,可将异常对象再抛出。
【示例5-8】 连续抛出异常的Java应用程序。
Java虚拟机执行程序是从main()方法开始的,即虚拟机调用main()方法,main()方法中的异常是抛给虚拟机的。当整数被0除时,虚拟机接到该异常只能终止程序的继续运行,Java虚拟机输出的异常信息为:
该信息表明,程序执行时出现ArithmeticException类型的异常,确切信息是“/by zero”,异常出现在division()和main()方法中,Java虚拟机将终止程序的运行。
5.3.2 针对被抛出的异常对象的处理
在编写Java应用程序时,一般要求在调用某个方法的同时,对该方法抛出的异常对象进行捕获和处理,除非被调用的方法抛出的异常对象不影响程序的正常运行才可以将它再抛出,实现异常对象的接力抛出。
另外,异常抛出throws语句经常与try-catch语句配合使用,当try程序模块体中确实有异常发生,但是,catch语句并没有捕获到,出现该情况时,需要将异常抛出。
【示例5-9】 捕获与抛出异常对象相结合的Java应用程序。
上述程序执行结果为:
在初始化数组initArray()方法中,只对整数被0除异常ArithmeticException进行了捕获和处理,但是,该段程序代码可能还会出现其他的异常,例如,数组越界异常ArrayIndexOutOfBoundsException。在编写应用程序时,有时并没有注意到其他的异常情况,也有可能不知道会发生什么异常情况,所以在编写程序时,可以将所有可处理异常的父类Exception类型的异常对象通过方法抛出,由于Java类库java.lang包是嵌入Java虚拟机中的,所有异常类都被创建为对象并注册在Java虚拟机中,而RuntimeException异常对象实现的功能是在Java虚拟机运行Java程序期间出现异常时,将异常的父类抛出,因此,通过对Exception异常的捕获,可以捕获到java.lang包中定义的Exception子类的所有异常类型,上述程序就是通过initArray()方法抛出异常,它将由调用initArray()方法的上一级main()方法对Exception类型的异常进行捕获和处理。
在编写Java应用程序用到try-catch语句结构时,如果catch语句无法匹配try语句中的代码产生的异常时,可以在方法的声明中将常规的可处理的异常抛出。