首页 理论教育 Java程序设计:捕获异常的三种处理方式

Java程序设计:捕获异常的三种处理方式

时间:2023-11-01 理论教育 版权反馈
【摘要】:捕获异常并处理的格式有三种,分别为try…其实,寻找异常处理器的过程就是捕获异常的过程。catch结构处理例5-1中的异常。异常捕获还可以包括finally代码块,它表示无论是否出现异常,都应当执行的内容。一般而言,为避免混淆,应该避免在finally代码块中使用return语句或者抛出异常,如果调用的其他代码可能抛出异常,则应该捕获异常并进行处理。

Java程序设计:捕获异常的三种处理方式

在方法抛出异常之后,JRE将转为寻找合适的异常处理器(exception handler)。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。JRE从发生异常的方法开始,依次回溯调用栈中的方法,直至找到含有合适异常处理器的方法并执行。捕获异常并处理的格式有三种,分别为try…catch、try…catch…finally和try…finally。

下面以try…catch…finally结构进行说明:

(1)try代码块中包含的语句在正常情况下会全部执行,但也有可能会发生异常,属于被监控的区域。当运行try代码块中的代码出现异常时,则会产生一个该类异常的对象,并将该异常对象抛出try代码块,正常的执行流程就被中断,try代码块中剩余的代码将不会执行,因此,try代码块中监控的语句要尽量少。

(2)JRE接收到该异常对象后,沿着方法调用链,反方向依次查找匹配的异常处理器(catch代码块)。如果是try代码块抛出异常对象,则依次匹配对应的catch代码块(如果存在多个catch代码块,应该尽量将捕获底层异常类的catch代码块放在前面,否则可能会被屏蔽或产生编译异常),当异常对象第一次匹配到对应catch代码块中异常类型(包括该异常类的子类)时,就将异常对象赋值给catch代码块声明的变量,执行catch代码块中的异常处理代码,异常捕获完成;如果在该方法没有匹配成功,则退出该方法,将异常对象传递给调用该方法的调用处,继续前面过程;如果在所有方法调用链中都找不到匹配的异常处理器,则程序终止并在控制台上打印异常对象信息。其实,寻找异常处理器的过程就是捕获异常的过程。

(3)不管try代码块里是否发生异常,finally代码块内的代码都会执行,一般用于释放资源,如关闭打开的数据库连接、文件等。

在try…catch结构中,没有finally代码块,表示如果有异常发生需要catch代码块捕获,但没有资源清理等收尾工作。在try…finally结构中,没有catch代码块,表示如果有异常抛出也不用捕获,但在异常被抛给上层调用者之前需要执行finally代码块。

【例5-2】

利用try…catch结构处理例5-1中的异常。

在例5-1中,当调用My Math1类的divide方法时产生除数为0的ArithmeticException异常,由于它是运行时异常,由JRE自动抛出。假设在main方法里将其捕获并处理,则需要用到try…catch结构或者try…catch…finally结构。

下面演示try…catch语句,测试类My Math1Test2如图5-4所示。

图5-4 try…catch结构处理异常

(1)本例中,main方法在程序第6行调用My Math1.divide(2,0),My Math1.divide(2,0)方法在执行时抛出异常(见My Math1类第5行),由于该代码并没有被监控,于是退出divide方法执行(产生异常后的剩余代码不再执行),将生成的异常对象抛给上层main方法第6行调用处,由于该调用语句被try代码块所包含,属于被监控语句,依次匹配该try代码块对应的catch代码块,被第一个catch代码块所捕获并处理,catch代码块执行完毕后,意味着try…catch结构结束,try代码块中剩余代码(第7行)不会被执行。注意,本例实际用不到第二个catch代码块,写上它只是为了讲解多个catch代码块需要。(www.xing528.com)

(2)该异常在main方法中被捕获,main方法将继续执行(第13行语句)。

(3)如果程序第6行不产生异常(例如改为My Math1.divide(2,5);),那么try代码块中的所有语句都会正常执行,而catch代码块中的语句不会执行。

(4)异常处理也可以在My Math1类的divide方法中捕获,这样,My Math1Test2类main方法调用该方法时就不用再进行异常处理。

【例5-3】

利用try…catch…finally结构处理例5-1中的异常。

异常捕获还可以包括finally代码块,它表示无论是否出现异常,都应当执行的内容。具体来说:如果没有异常发生,在try内的代码执行结束后执行;如果有异常发生且被catch捕获,在catch内的代码执行结束后执行;如果有异常发生但没被捕获,则在异常被抛给上层之前执行。

程序演示如图5-5所示。

图5-5 try…catch…finally结构处理异常

(1)无论是否捕获异常,finally代码块里的语句都会被执行,就算在try代码块或catch代码块中遇到return语句,finally代码块也会在方法返回前被执行。特殊情况下,例如try代码块或catch代码块中使用System.exit()退出程序等,finally代码块中的语句才不会被执行。

(2)一般而言,为避免混淆,应该避免在finally代码块中使用return语句或者抛出异常,如果调用的其他代码可能抛出异常,则应该捕获异常并进行处理。

(3)从类java.lang.Throwable继承的方法public void printStack Trace(),将此Throwable对象的堆栈跟踪输出至错误输出流,作为字段System.err的值。输出的第一行包含此对象的toString()方法的结果,剩余行表示以前由方法fillInStack Trace()记录的数据。此信息的格式取决于实现。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈