try...catch和finally
当程序发生异常时,会立即终止,无法继续向下执行。为了保证程序能够有效的执行,Java中提供了一种对异常进行处理的方式——异常捕获。
异常捕获通常使用try…catch语句,其具体语法格式如下:
try {
// 可能发生异常的语句
} catch(Exception类或其子类 e){
// 对捕获的异常进行相应处理
}
上述代码中,try{}代码块中包含的是可能发生异常的语句,catch(){}代码块中编写针对捕获的异常进行处理的代码。当try{}代码块中的程序发生了异常,系统会将这个异常的信息封装成一个异常对象,并将这个对象传递给catch(){}代码块。catch(){}代码块需要一个形参指明它所能够接收的异常类型,这个参数的类型必须是Exception类或其子类。
接下来使用try...catch语句对文件4-28中出现的异常进行捕获和处理,如文件1所示。
文件1 Example29.java
1 public class Example29 {
2 // 下面的方法实现了两个整数相除
3 public static int divide(int x, int y) {
4 try {
5 int result = x / y; // 定义一个变量result记录两个数相除的结果
6 return result; // 将结果返回
7 } catch (Exception e) { // 对异常进行捕获处理
8 System.out.println("捕获的异常信息为:" + e.getMessage());
9 }
10 // 定义当程序发生异常直接返回-1
11 return -1;
12 }
13 public static void main(String[] args) {
14 int result = divide(4, 0); // 调用divide()方法
15 if(result == -1){ // 对调用方法返回结果进行判断
16 System.out.println("程序发生异常!");
17 }else{
18 System.out.println(result);
19 }
20 }
21 }
运行结果如图1所示。
图1 运行结果
文件1中,在定义的整数除法运算方法divide()中对可能发生异常的代码用try…catch语句进行了捕获处理。在try{}代码块中发生被0除异常,程序会转而执行catch(){}中的代码,通过调用Exception对象的getMessage()方法,即可返回异常信息“/ by zero”。catch(){}代码块对异常处理完毕后,程序仍会向下执行,而不会因为异常而终止运行。
需要注意的是,在try{}代码块中,发生异常语句后面的代码是不会被执行的,如文件4-29中第6行代码的return语句就没有执行。
在程序中,有时候会希望有些语句无论程序是否发生异常都要执行,这时就可以在try…catch语句后,加一个finally{}代码块。接下来对文件4-29进行修改,演示一下finally{}代码块的用法,如文件2所示。
文件2 Example30.java
1 public class Example30 {
2 // 下面的方法实现了两个整数相除
3 public static int divide(int x, int y) {
4 try {
5 int result = x / y; // 定义一个变量result记录两个数相除的结果
6 return result; // 将结果返回
7 } catch (Exception e) { // 对异常进行捕获处理
8 System.out.println("捕获的异常信息为:" + e.getMessage());
9 } finally {
10 System.out.println("执行finally代码块,无论程序是否异常,都会执行");
11 }
12 // 定义当程序发生异常直接返回-1
13 return -1;
14 }
15 public static void main(String[] args) {
16 int result = divide(4, 0); // 调用divide()方法
17 if(result == -1){ // 对调用方法返回结果进行判断
18 System.out.println("程序发生异常!");
19 }else{
20 System.out.println(result);
21 }
22 }
23 }
运行结果如图2所示。
图2 运行结果
文件2中,divide()方法中增加了一个finally{}代码块,用于处理无论程序是否发生异常都要执行的语句,该代码块并不受return语句和程序异常的影响。正是由于这种特殊性,在程序设计时,经常会在try...catch后使用finally{}代码块来完成必须做的事情,例如释放系统资源、关闭线程池等。
需要注意的是,finally中的代码在一种情况下是不会执行的,那就是在try...catch中执行了System.exit(0)语句。System.exit(0)表示退出当前的Java虚拟机,Java虚拟机停止了,任何代码都不能再执行了。