11.2 捕获异常

捕获异常必须设置try/catch语句块,最简单的try语句:

  1. try {  
  2.     //code  
  3.     //more code  
  4. catch (ExceptionType e){  
  5.     //handler for this type  
  6. }  
1、如果在try语句中的任何代码抛出了catch子句中说明的异常类:

1)程序跳过try语句块的其余代码

2)程序执行catch字句中的处理器代码

2、如果try语句块中没有抛出任何异常类则跳过catch子句。

3、如果方法中任何代码抛出了在catch子句中没有声明的异常类型,该方法会立即退出。

  1. public void read(String filename) {  
  2.         try {  
  3.             InputStream in = new FileInputStream(filename);  
  4.             int b;  
  5.             while ((b = in.read()) != -1) {  
  6.                 //process input  
  7.             }  
  8.         }   
  9.         catch (IOException exception) {  
  10.             exception.printStackTrace();  
  11.         }  
  12.     }  

11.2.1捕获多个异常

  1. try {  
  2.         //code that might throw exceptions  
  3.     }  
  4.     catch (MalformedURLException e1) {  
  5.         //emergency action for malformed URLs  
  6.     }  
  7.     catch (UnknownHostException e2) {  
  8.         //emergency action for malformed hosts  
  9.     }  
  10.     catch (IOException e3) {  
  11.         //emergency action for all other I/O problems  
  12.     }  
要想获得对象更多的信息,可以使用:e3.getMessage()

想得到详细的错误信息(如果有的话),使用:e3.getClass().getName()得到异常对象的实际类型


11.2.2再次抛出异常与异常链接

在catch子句中可以抛出一个异常,这样可以改变异常的类型。

下面是捕获异常并再次抛出的基本方法:

  1. try {  
  2.     //access the database  
  3. }  
  4. catch (SQLException e) {  
  5.     Throwable se = new ServletException("database error");  
  6.     se.initCause(e);  
  7.     throw se;  
  8. }  
捕获异常后可以用Throwable e = se.getCause();语句得到原始异常。


11.2.3Finally子句

不管是否有异常被捕获,都要执行finally子句中的代码。

下列例子程序将释放所以环境中的图形设备文本:

  1. Graphics g = image.getGraphics();  
  2. try {  
  3.     //1  
  4.     code that might throw exceptions  
  5.     //2  
  6. }  
  7. catch (IOException e){  
  8.     //3  
  9.     show error dialog  
  10.     //4  
  11. }  
  12.   
  13. finally {  
  14.     //5  
  15.     g.dispose();  
  16. }  
  17. //6  
下列三种情况会执行finally子句:

1)代码没有抛出异常;程序执行1、2、5、6

2)抛出一个在catch处捕获的异常;执行1、3、4、5、6

3)抛出一个异常但不是由catch捕获的;执行1、5


try语句中可以只有finally子句没有catch子句,例如:

  1. InputStream in = ...'  
  2. try {  
  3.     code that might throw exceptions  
  4. }  
  5. finally {  
  6.     in.close();  
  7. }  
无论try中是否遇到异常,finally子句都被执行。


警告:当finally子句和try语句块中都有return语句时,finally的return值会覆盖掉try的return值。例如:

  1. public static int f(int n) {  
  2.     try {  
  3.         int r = n * n;  
  4.         return r;  
  5.     }  
  6.     finally {  
  7.         if (n == 2)  
  8.             return 0;  
  9.     }  
  10. }  
如果调用f(2),try的返回值是4,finally返回值是0,最后结果为0


11.2.4 分析堆栈跟踪元素
例11-1打印递归阶乘的堆栈情况:

  1. package core.stacktracetest_11_1;  
  2.   
  3. import java.util.Scanner;  
  4.   
  5. /** 
  6.  * @author vincent 
  7.  */  
  8. public class StackTraceTest {  
  9.   
  10.     public static int factorial(int n) {  
  11.         System.out.println("factorial(" + n + "):");  
  12.           
  13.         Throwable t = new Throwable();  
  14.         StackTraceElement[] frames = t.getStackTrace();  
  15.         for (StackTraceElement f : frames)  
  16.             System.out.println(f);  
  17.   
  18.         int r;  
  19.         if (n <= 1) r = 1;  
  20.         else r = n * factorial(n - 1);  
  21.         System.out.println("return" + r);  
  22.         return r;  
  23.     }  
  24.   
  25.     public static void main(String[] args) {  
  26.         @SuppressWarnings("resource")  
  27.         Scanner in = new Scanner(System.in);  
  28.         System.out.println("Enter n: ");  
  29.         int n = in.nextInt();  
  30.         factorial(n);  
  31.     }  
  32. }  

你可能感兴趣的:(java)