前面了解了Java异常和异常处理类,本课讲述如何使用try和catch语句捕获异常。
Java程序在执行过程中如果出现异常,会自动生成一个异常对象,该异常对象将被自动提交给JVM,当JVM接收到异常对象时,会寻找能处理这一异常的代码,并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。如果JVM找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。
在java中添加捕获异常代码时,需要把认为可能会出现异常的代码包括在try语句块内,处理异常的代码包括在catch语句块内。在程序执行时,如果try语句内的代码出现错误,try会创建异常对象并抛出,catch捕获异常对象,catch语句块内的代码将会执行,这样就可以处理异常错误了。
使用try和catch的语法规则如下:
try {
可能发生异常的代码
}
catch(异常类型 ex) {
对异常进行处理的代码
}案例1:建立一个测试类,在main()方法中使用try-catch语句捕获和处理异常。
在excep包下新建TryTest类。代码如下:
public class TryTest {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param @param args 参数
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int number = -1;
Scanner in = new Scanner(System.in);
try {
number = Integer.parseInt(in.nextLine());
//如果存在异常,下面这行代码是不会输出的
System.out.println("程序没有发生异常");
System.out.println("您输入的数字为:" + number);
} catch(Exception e) {
System.out.println("非法的数字");
}
System.out.println("程序运行结束");
}
}上面的代码通过Scanner获取用户输入的字符串,然后将字符串转换为整数。如果用户输入不是数字型字符串,转换过程将会发生异常,发生的异常会被catch内的语句块处理。
通过案例可以发现,当程序没有异常时,catch内的语句不会被执行。当程序有异常时,如果被try语句捕获到,将会执行catch内的语句,catch后面的代码也会被执行。如果异常没有被try语句捕获到,异常会向上抛出,即返回调用当前代码的位置,如果该位置未对异常进行处理,则继续向上抛出,直至被JVM捕获异常,JVM会停止程序的运行。
前面介绍的是处理单个异常,有时代码可能会引发多个异常,在这种情况下,可以定义两个或更多的catch子句,每个子句捕获一种类型的异常。
多重catch语句的语法规则如下:
try {
………. //代码段
………. //产生异常
}
catch(异常类型1 ex) {
………. //对异常1进行处理代码段
} catch(异常类型2 ex) {
………. //对异常2进行处理代码段
}
} catch(异常类型n ex) {
………. //对异常n进行处理代码段
}案例2:建立MultiCatchTest类,进行多异常处理。
在excep包下新建MultiCatchTest类。代码如下:
public class MultiCatchTest {
/**
* @Title: main
* @Description: Java程序入口main方法
* @param @param
* args 参数
* @return void 返回类型 @throws
*/
public static void main(String[] args) {
try {
// 获取args数组长度
int a = args.length;
// 输出args数组长度
System.out.println("args数组长度为:" + a);
//执行除法操作
int b = 42 / a;
// 定义c数组,从数组的长度为1
int c[] = { 1 };
// 给c数组第9个元素赋值
c[10] = 99;
} catch (ArithmeticException e) {
System.out.println("Divide by 0: " + e);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index oob: " + e);
}
System.out.println("After try/catch blocks.");
}
}代码在没有命令行输入参数条件下运行导致被零除异常,因为a为0。如果输入一个命令行参数,把a设成大于零的数值,就不会出现被零除的异常。但是它将导致ArrayIndexOutOf BoundsException异常,因为整型数组c的长度为1,而程序试图给c[10]赋值。
从案例2可以看出,一段代码中可能会产生多种不同的异常,可以设置多个异常抛出点来解决这个问题。
异常对象从被抛出到捕捉,实际上是一个执行控制权转移的过程,所以可以根据程序需要合理地控制检测到异常的粒度。如果并不需要知道具体产生的是什么异常,那么可以使用异常的公共父类Exception来处理异常对象,即catch(Exception e){…} 。