当前位置:课程学习>>第六章 异常处理>>文本学习>>知识点二
在Java程序中可以使用try-catch-finally语句来捕获和处理异常,这样可以避免程序自动终止。其格式为:
try
{
可能会发生异常的Java程序段
}
catch(异常类1 对象名1)
{
针对异常类1的处理语句
}
catch(异常类2 对象名2)
{
针对异常类2的处理语句
}
……
finally
{
最终运行语句
}
(1) try块:用来包含可能抛出异常的程序段,可以是方法的调用,也可以是复杂的语句序列。
(2) catch块:用来捕获指定的异常,并进行相应处理。它必须紧跟try块,可以定义多个catch块。每个catch语句中都有一个参数即异常类对象,其类型可以是要捕获的异常类或其父类。若是Exception,则可以捕获所有的异常。try块中一旦某条语句发生了异常,就会自动跳出try块,查找相应的catch块,找到后就执行catch块中的语句序列。try块中剩下的语句和其他的catch块都不会再被运行。如果多个catch块中的异常类存在父类和子类的关系,要求必须把子类的catch块放在前面,否则编译就会出现问题。
(3) finally块:finally块是可选的,它为异常处理提供了一个统一的出口,无论程序中是否出现异常,也不论出现什么异常,finalyy块中的语句均要被执行一遍。finally块中的语句一般是进行资源清除工作,如关闭已经打开的文件等。即使在try块中有return语句,finally块也会被执行,即finally语句是在return语句之前被执行的。
【例5.3】异常处理语句。
1 //FinallyTest.java
2 public class FinallyTest
3 {
4 int func1()
5 {
6 int ret=1;
7 try
8 {
9 System.out.println("In try statement");
10 return ret;
11 }
12 catch(Exception e)
13 {
14 System.out.println("In catch statement");
15 }
16 finally
17 {
18 System.out.println("In finally statement");
19 ret=2;
20 // return ret;
21 }
22 return 3;
23 }
24 public static void main(String[] args)
25 {
26 int r;
27 FinallyTest ft=new FinallyTest();
28 r=ft.func1();
29 System.out.println("return r="+r);
30 }
31 }
编译运行该程序,程序结果为:
In try statement
In finally satement
return r=1
如果把第20行的注释去掉,同时把第22行加上注释,重新编译运行该程序,其结果为:
In try statement
In finally satement
return r=2
这个程序说明了finally语句要在return语句执行之前被执行,同时在finally块中是不能够通过重新赋值的方式来改变 return 语句的返回值。
二、声明抛出异常
对于出现的异常除了使用try……catch……finally语句来处理外,还可以在方法定义时声明抛出异常,这样就不需要在方法中处理该异常,而是留给了方法的调用者。声明抛出异常的格式为:
返回值类型 方法名([参数列表]) throws 异常列表
发生在方法内的异常若是RuntimeException或Error,则可以不用捕获处理或声明抛出,但对于非运行时异常则必须捕获处理或声明抛出。此外子类方法中抛出的异常只能是父类方法抛出异常的同一个类或其子类。
在方法定义时使用throws 异常列表形式声明抛出异常,但并不能说明方法中就一定会产生该异常,有两种情况就不会有异常:一是方法体中的语句本来就不会出现异常,二是在方法中已经使用了try……catch语句对产生的异常进行了捕获处理。
【例5.4】声明抛出异常。
1 //ThrowsExceptionTest.java
2 public class ThrowsExceptionTest
3 {
4 void func1() throws Exception
5 {
6 int a=3,b=4,c;
7 c=b/a;
8 System.out.println("In func1");
9 }
10 void func2() throws Exception
11 {
12 int a=3,b=0,c=1;
13 System.out.println("In func2");
14 try
15 {
16 c=a/b;
17 System.out.println("In func2 try");
18 }
19 catch(Exception e)
20 {
21 System.out.println("catch in func2");
22 }
23 }
24 void func3()
25 {
26 int a=3,b=0,c;
27 System.out.println("In func3");
28 c=a/b;
29 System.out.println("In func3,c="+c);
30 }
31 void func4() throws Exception
32 {
33 int a=3,b=0,c;
34 System.out.println("In func4");
35 c=a/b;
36 System.out.println("In func4,c="+c);
37 }
38 public static void main(String[] args)
39 {
40 ThrowsExceptionTest tet=new ThrowsExceptionTest();
41 try
42 {
43 tet.func1();
44 }
45 catch(Exception e)
46 {
47 System.out.println("func1 exception catch in main");
48 }
49 try
50 {
51 tet.func2();
52 }
53 catch(Exception e)
54 {
55 System.out.println("func2 exception catch in main");
56 }
57 try
58 {
59 tet.func3();
60 }
61 catch(Exception e)
62 {
63 System.out.println("func3 exception catch in main");
64 }
65 try
66 {
67 tet.func4();
68 }
69 catch(Exception e)
70 {
71 System.out.println("func4 exception catch in main");
72 }
73 }
74 }
程序运行结果如图5.4所示。
图5.4 声明异常程序运行结果
三、获取异常信息
Throwable类中提供了用来获取异常对象信息的方法,主要有:
String getMessage():获取异常的详细描述信息;
String toString():获取异常的简短信息,
若对象是利用非空字符串创建的,则结果是三个字符串的串联:此对象实际的类名、“:”(冒号和空格)、此对象的getMessage()方法的结果。如果此Throwable对象利用null字符串创建,只返回此对象实际的类名;
void printStackTrace():输出异常的简短信息和方法调用堆栈信息到标准错误输出流(一般为显示器)。输出的第一行是toString()的结果,后面是fillInStackTrace()的输出结果。
【例5.5】获取异常信息。
1 //GetExceptionMessage.java
2 public class GetExceptionMessage
3 {
4 static void func1()
5 {
6 System.out.println("in func1");
7 int c=4/0;
8 }
9 static void func2()
10 {
11 System.out.println("in func2");
12 func1();
13 }
14 public static void main(String[] args)
15 {
16 try
17 {
18 func2();
19 }
20 catch(Exception e)
21 {
22 System.out.println("getMessage()="+e.getMessage());
23 System.out.println("toString()="+e.toString());
24 e.printStackTrace();
25 }
26 }
27 }
程序的运行结果如5.5所示。注意getMessage()方法、toString()方法以及printStackTrace()方法的输出结果。
图5.5 获取到的异常信息
四、自定义异常类
在Java中除了Java已经提供的那些异常类外,用户还可以根据需要自己定义一个或多个异常类,一般要继承Exception或RuntimeException,在异常类中可以通过有参数的构造方法来传递该异常的描述信息。
【例5.6】自定义异常。
1 //MyExceptionTest.java
2 class MyException extends Exception
3 {
4 MyException()
5 {
6
7 }
8 MyException(String str)
9 {
10 super(str);
11 }
12 }
13 public class MyExceptionTest
14 {
15 public static void main(String[] args)
16 {
17 try
18 {
19 System.out.println("throw my exception 1");
20 throw new MyException();
21 }
22 catch(Exception e)
23 {
24 System.out.println("catch my exception 1");
25 System.out.println(e.getMessage());
26 e.printStackTrace();
27 }
28 try
29 {
30 System.out.println("throw my exception 2");
31 throw new MyException("my exception");
32 }
33 catch(Exception e)
34 {
35 System.out.println("catch my exception 2");
36 System.out.println(e.getMessage());
37 e.printStackTrace();
38 }
39 }
40}
程序运行结果如图5.6所示。
图5.6 程序运行结果