(一)、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
