|
点击此处返回总目录
对于异常共有两种处理方式:一种是使用try...catch进行捕获处理,另一种是继续抛出。现在讲解try...catch...finally。
一、try...catch...finally异常处理
当执行程序时,可能抛出异常。可以使用如下的格式对可能出现异常的程序捕获异常并处理。
格式:
try{
//被检测的代码。有可能会产生异常的代码。
}catch(异常类名 变量){
//异常的处理
//这里面可以任意写,比如写循环、遍历、调用方法、变量运算等都是可以的。只要有catch就叫处理了异常。
}finally{
//必须要执行代码
}
注意:
1. 如果在try中产生了异常,则程序会自动跳转到catch语句中找到匹配的异常类型进行相应的处理。最后不管程序是否产生异常,都会执行finally语句。finally语句可以省略。如果finally块不写,则在catch()块运行结束后,程序调到try...catch块后面继续执行。【例1】【例2】
异常的处理流程如下:

2. catch捕获到异常之后,往往有三种处理方式,第三种方式最全最常用。
方式一:
catch(exception ex){
System.out.println(ex.getMessage); //把构造器中的信息输出来。
}
方式二:
catch(exception ex){
System.out.println(ex.toString()); //不但有异常的信息,而且有异常类名。
}
方式三:
catch(exception ex){
ex.printStackTrace(); //打印堆栈信息。
}
3. finally语句块,无论代码是否产生异常,finally语句必须执行。finally用于释放资源。比如打开一个文件,当出了异常之后也要关闭文件。
例1:分析下列程序的执行结果:
|
package cn.itcast.demo04;
public class Test {
public static void main(String[] args) {
int[] arr = {1,22,3};
try{
int i = arr[3];
System.out.println("cccc");
}catch(Exception e){
e.printStackTrace();
System.out.println("aaaa");
}
System.out.println("bbbb"); //对异常进行处理之后,后续代码还能继续执行。
}
}
|
运行结果:
java.lang.ArrayIndexOutOfBoundsException: 3
at cn.itcast.demo04.Test.main(Test.java:7)
aaaa
bbbb
分析:
"cccc"是不被打印出来的。
例2:分析下列程序的运行结果:
|
package cn.itcast.demo04;
public class Test {
public static void main(String[] args){
try{
int i = Integer.parseInt(args[1]);
int j = Integer.parseInt(args[2]);
int k = i/j;
System.out.println("结果是:"+k);
}catch(ArithmeticException e){
e.printStackTrace();
System.out.println("异常处理");
}finally{
System.out.println("finally语句");
}
System.out.println("后续语句");
}
}
|
运行结果:
finally语句
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at cn.itcast.demo04.Test.main(Test.java:7)
结果分析:
执行到int i 这一句时,产生异常。try中后续代码不再执行。catch没有捕获到相应的异常。执行finally语句。异常没有被处理,所以交给JVM处理。后续语句不再执行。
例3:分析下列程序的运行结果:
|
package cn.itcast.demo04;
public class Test {
public static void main(String[] args) {
int arr[] = {1,2,3};
System.out.println(arr[3]); //数组下标越界异常。
}
}
|
运行结果:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at cn.itcast.demo04.Test.main(Test.java:6)
分析:main执行时出现了异常。main中没有捕获这种异常的代码,所以这个异常抛出给了JVM,JVM将异常的信息以红色字体输出到控制台,并将程序停止。
例4:分析下列程序的运行结果:
|
1 package cn.itcast.demo01;
2
3 public class Test {
4 public static void main(String[] args) { //也可以在这里面处理,也可以抛出
5 int[] arr = {1,2,3};
6 int a = fun(arr);
7 System.out.println(a);
8 }
9
10 public static int fun(int[] arr){ //既可以在这里处理异常,也可以抛出
11 int i = arr[9];
12 return i+1;
13 }
14 }
|
运行结果如下:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9 //程序报了数组越界异常,9索引不对,没有9索引。
at cn.itcast.demo01.Test.fun(Test.java:11) //发生在Test类的11行。
at cn.itcast.demo01.Test.main(Test.java:6) //还发生在第6行。
程序报了数组越界异常,我们看一下报错是怎么产生的,以及怎么处理的。分析如下:
步骤1:程序执行到第6行,main函数调用fun()
步骤2:当执行到第11行时,数组arr没有9索引,JVM检测到出现了数组越界问题。这时,JVM做了两件事情:
1.创建了异常的对象,并在构造器里放了个“9”,表示9索引出了问题: new ArrayIndexOutOfBoundsException(9)
2.在本方法,即fun()方法内找有没有处理异常的程序,找不到,于是将异常的对象抛出,抛给方法的调用者main()
注意,一旦异常被抛出了,后面的代码就不执行了,所以第12行没有执行。
步骤3:main收到异常,开始找自己的方法有没有处理异常的代码,也没有,于是将异常对象继续抛出,抛给了main()的调用者JVM
注意,一旦异常被抛出了,后面的代码就不执行了,所以第7行没有执行。
步骤4:JVM收到异常之后,JVM也做了两件事情:
1. 将异常信息以红色字体输出到控制台
2.将程序停止、结束
二、多catch处理
对于上面的例2,实际上存在3种异常:当不输入参数时,ArrayIndexOutOfBoundException;当输入的参数不是数字时,NumberFormatException;当除数为0时,ArithmeticException。而程序中只捕获了一种异常,对于不能不能捕获的另外两种异常,程序依然会直接中断,所以为了保证出现3种异常后都能够正确处理,可以使用多个catch捕获。【例1】
注意:当写多个catch时,有顺序关系。
对于平级异常,顺序无所谓。但是对于有继承关系的异常,必须先捕获子类异常,然后捕获父类异常。【例2】。如果先捕获父类的,再捕获子类的,会报错。原因就是多态,父类的catch可以匹配到子类的异常,导致子类的catch没有用了。【例3】
例1:
|
package cn.itcast.demo04;
public class Test {
public static void main(String[] args){
try{
int i = Integer.parseInt(args[1]);
int j = Integer.parseInt(args[2]);
int k = i/j;
System.out.println("结果是:"+k);
}catch(ArithmeticException e){
e.printStackTrace();
System.out.println("除0异常");
}catch(NumberFormatException e){
e.printStackTrace();
System.out.println("输入的不是数字");
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
System.out.println("数组下标越界");
}finally{
System.out.println("finally语句");
}
System.out.println("后续语句");
}
}
|
运行结果:
java.lang.ArrayIndexOutOfBoundsException: 1
at cn.itcast.demo04.Test.main(Test.java:7)
数组下标越界
finally语句
后续语句
例2:先写子类catch,然后写父类catch,正确。
|
package cn.itcast.demo05;
public class Test {
public static void main(String[] args) {
try{
int i = 2;
}catch(IndexOutOfBoundsException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
}
|
例3:先写父类catch,然后写子类catch,程序出错。
|
package cn.itcast.demo05;
public class Test {
public static void main(String[] args) {
try{
int i = 2;
}catch(Exception e){
e.printStackTrace();
}catch(IndexOutOfBoundsException e){
e.printStackTrace();
}
}
}
|
|