Java 異常的捕獲與處理詳解(二)


(一)、throws關鍵字

  throws關鍵字主要是在定義上使用的,表示的是此方法中不進行異常處理,而交給被調用處處理。

  例如:

1 class MyMath {
2     public int div(int x, int y) throws Exception {
3         return x / y;
4     }
5 }

  現在div()方法之中拋出一個異常出來,表示所有異常交給被調用處進行處理。

 1 class MyMath {
 2     public int div(int x, int y) throws Exception {
 3         return x / y;
 4     }
 5 }
 6 
 7 public class Test {
 8     public static void main(String args[]) {
 9         try {
10             System.out.println(new MyMath().div(10, 0));
11         } catch (Exception e) {
12             e.printStackTrace();
13         }
14     }
15 }

運行結果:

1 java.lang.ArithmeticException: / by zero
2     at MyMath.div(Test.java:3)
3     at Test.main(Test.java:10)

注意:在調用throws關鍵字聲明方法的時候,一定要使用異常處理操作進行異常的處理,這屬於強制性的處理。

而主方法本身也屬於方法,那么在主方法上也可以繼續使用throws進行異常的拋出:

 

 1 class MyMath {
 2     public int div(int x, int y) throws Exception {
 3         return x / y;
 4     }
 5 }
 6 
 7 public class Test {
 8     public static void main(String args[]) throws Exception {
 9         System.out.println(new MyMath().div(10, 0));
10     }
11 }

 

運行結果:

1 Exception in thread "main" java.lang.ArithmeticException: / by zero
2     at MyMath.div(Test.java:3)
3     at Test.main(Test.java:9)

這時主方法將異常繼續向上拋,交給JVM進行異常的處理,也就是采用默認的方式,輸出異常信息,而后結束程序執行。

注意:在實際開發中,主方法不要加throws,因為程序如果有異常,我們也希望可以正常的結束。

(二)throw關鍵字

  之前所有異常類的對象都是由JVM自動進行實例化操作的,用戶自己也是可以手工地拋出一個異常類實例化對象,就通過throw完成了。

 

1 public class Test {
2     public static void main(String args[]) {
3         try {
4             throw new Exception("自定義的異常");
5         } catch (Exception e) {
6             e.printStackTrace();
7         }
8     }
9 }

 

運行結果:

1 java.lang.Exception: 自定義的異常
2     at Test.main(Test.java:4)

小結:throw和throws的區別?

  (1)throw: 在方法體內使用,表示人為地拋出一個異常類對象(這個對象可以是自己實例化的,也可以是已經存在的)

 

 

 

  (2)throws: 在方法的聲明上使用,表示此方法中不進行異常的處理,而交給被調用處處理。

 

(三)、異常處理標准格式

我們有種感覺,finally和throw沒有用處。現要求定義一個div()方法,這個方法有如下的一些要求: 
(1)在進行除法操作之前,輸出一行提示信息; 
(2)在除法操作執行完畢后,輸出一行提示信息; 
(3)如果中間產生了異常,則應該交給被調用處來進行處理。

 1 class MyMath {
 2     // 出現異常要交給被調用處出,使用throws
 3     public int div(int x, int y) throws Exception {
 4         System.out.println("===== 計算開始 ====="); 
 5         int result = 0;
 6         try {
 7             result = x / y; // 除法計算
 8         } catch (Exception e) {
 9             throw e; // 向上拋
10         } finally {
11             System.out.println("===== 計算結束 ====="); 
12         }
13         return result;
14     }
15 }
16 
17 public class Test {
18     public static void main(String args[]) {
19         try {
20             System.out.println(new MyMath().div(10, 0));
21         } catch (Exception e) {
22             e.printStackTrace();
23         }
24     }
25 }

運行結果:

1 ===== 計算開始 =====
2 ===== 計算結束 =====
3 java.lang.ArithmeticException: / by zero
4     at MyMath.div(Test.java:7)
5     at Test.main(Test.java:20)

以上代碼也可以做一些簡化:

 1 class MyMath {
 2     // 出現異常要交給被調用處出,使用throws
 3     public int div(int x, int y) throws Exception {
 4         System.out.println("===== 計算開始 ====="); 
 5         int result = 0;
 6         try {
 7             result = x / y; // 除法計算
 8         } finally {
 9             System.out.println("===== 計算結束 =====");
10         }
11         return result;
12     }
13 }
14 
15 public class Test {
16     public static void main(String args[]) {
17         try {
18             System.out.println(new MyMath().div(10, 0));
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 }

運行結果:

1 ===== 計算開始 =====
2 ===== 計算結束 =====
3 java.lang.ArithmeticException: / by zero
4     at MyMath.div(Test.java:7)
5     at Test.main(Test.java:18)

直接使用try…finally,不帶有catch,那么就連處理的機會都沒有了,所以不建議使用try…finally。標准格式是try…catch、finally、throws、throw一起使用。

 

(四)、RuntimeException類

  先來觀察一段代碼

1 public class Test {
2     public static void main(String args[]) {
3         String str = "123";
4         int num = Integer.parseInt(str);
5         System.out.println(num * num);
6     }
7 }

運行結果:

1 15129

這個程序就是將一個字符串變為了基本數據類型,而后執行乘法操作,但是下面來看一下parseInt()方法定義:

1 public static int parseInt(String s) throws NumberFormatException

發現這個方法上拋出了一個NumberFormatException的異常,按照之前所講,如果存在了throws,則必須使用try…catch進行處理,可是現在卻沒有強制要求處理,這是為什么呢? 
來觀察一下NumberFormatException的繼承結構:

1 java.lang.Object
2    |- java.lang.Throwable
3       |- java.lang.Exception
4           |- java.lang.RuntimeException
5               |- java.lang.IllegalArgumentException
6                   |- java.lang.NumberFormatException

發現NumberFormatException屬於RuntimeException的子類,而在Java之中明確規定:對於RuntimeException的異常類型,在編譯的時候不會強制性的要求用戶處理,用戶可以根據需要有選擇性的來進行處理,在開發之中,如果沒有處理,那么出現異常之后將交給JVM默認進行處理。也就是說,RuntimeException的子異常類,可以由用戶根據需要有選擇性的來進行處理。

小結:RuntimeException和Exception的區別?請列舉出幾個常見的RuntimeException.

(1)RuntimeException是Exception的子類; 
(2)Exception定義了必須處理的異常,而RuntimeException定義的異常可以選擇性的進行處理。

常見的RuntimeException: 
NumberFormatException、ClassCastException、NullPointerException、ArithmeticException、ArrayIndexOutOfBoundsException。

 

五、assert關鍵字(斷言)

Java中斷言指的是程序執行到某行之后,其結果一定是預期的結果,而在JDK 1.4之后增加了一個assert關鍵字。

兩種語法形式: 
(1)形式一:

1 assert condition;

這里condition是一個必須為真(true)的表達式。如果表達式的結果為true,那么斷言為真,並且無任何行動 
如果表達式為false,則斷言失敗,則會拋出一個AssertionError對象。這個AssertionError繼承於Error對象。

(2)形式二:

1 asser condition:expr;

這里condition是和上面一樣的,這個冒號后跟的是一個表達式,通常用於斷言失敗后的提示信息,說白了,它是一個傳到AssertionError構造函數的值,如果斷言失敗,該值被轉化為它對應的字符串,並顯示出來。

使用斷言:

1 public class Test {
2     public static void main(String args[]) {
3         int x = 10;
4         // 假設經過了若干操作
5         assert x == 30 : "x的內容不是30";
6         System.out.println(x);
7     }
8 }

默認情況下,Java之中的斷言,不會在正常執行的代碼中出現,如果要想啟用斷言,則應該增加-ea選項:

1 java -ea Test

運行結果:

1 Exception in thread "main" java.lang.AssertionError: x的內容不是30
2         at Test.main(Test.java:5)

(六)、自定義異常

在Java之中本身已經提供了大量的異常類型,但是在開發之中,這些異常類型還不能滿足於開發的需要。所以在一些系統架構之中往往會提供一些新的異常類型,來表示一些特殊的錯誤,而這種操作就稱為自定義異常類,而要想實現這種自定義異常類,那么可以讓一個類繼承Exception或RuntimeException。

 1 class MyException extends Exception { // 自定義異常類
 2     public MyException(String msg) {
 3         super(msg);
 4     }
 5 }
 6 
 7 public class Test {
 8     public static void main(String args[]) throws Exception {
 9         throw new MyException("自己的異常類");
10     }
11 }

運行結果:

Exception in thread "main" MyException: 自己的異常類
    at Test.main(Test.java:9)

參考鏈接: http://blog.csdn.net/wei_zhi/article/details/52837635

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM