【Java學習筆記之三十二】淺談Java中throw與throws的用法及異常拋出處理機制剖析
異常處理機制
異常處理是對可能出現的異常進行處理,以防止程序遇到異常時被卡死,處於一直等待,或死循環。
異常有兩個過程,一個是拋出異常;一個是捕捉異常。
拋出異常
拋出異常有三種形式,一是throw,一個throws,還有一種系統自動拋異常。下面它們之間的異同。
系統自動拋異常
當程序語句出現一些邏輯錯誤、主義錯誤或類型轉換錯誤時,系統會自動拋出異常。如:
1 public static void main(String[] args) {
2 int a = 5, b =0;
3 System.out.println(5/b);
4 //function();
5 }
系統會自動拋出ArithmeticException異常:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.ExceptionTest.main(ExceptionTest.java:62)
再如
1 public static void main(String[] args) {
2 String s = "abc";
3 System.out.println(Double.parseDouble(s));
4 //function();
5 }
系統會自動拋出NumberFormatException異常:
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
at java.lang.Double.parseDouble(Double.java:510)
at test.ExceptionTest.main(ExceptionTest.java:62)
throw
throw是語句拋出一個異常。
語法:throw (異常對象);
如: throw e;
一般會用於程序出現某種邏輯時程序員主動拋出某種特定類型的異常。如:
1 public static void main(String[] args) {
2 String s = "abc";
3 if(s.equals("abc")) {
4 throw new NumberFormatException();
5 } else {
6 System.out.println(s);
7 }
8 //function();
9 }
會拋出異常:
Exception in thread "main" java.lang.NumberFormatException
at test.ExceptionTest.main(ExceptionTest.java:67)
throws
throws是方法可能拋出異常的聲明。(用在聲明方法時,表示該方法可能要拋出異常)
語法:[(修飾符)](返回值類型)(方法名)([參數列表])[throws(異常類)]{......}
如: public void function() throws Exception{......}
當某個方法可能會拋出某種異常時用於throws 聲明可能拋出的異常,然後交給上層調用它的方法程序處理。如:
1 public static void function() throws NumberFormatException{
2 String s = "abc";
3 System.out.println(Double.parseDouble(s));
4 }
5
6 public static void main(String[] args) {
7 try {
8 function();
9 } catch (NumberFormatException e) {
10 System.err.println("非數據類型不能轉換。");
11 //e.printStackTrace();
12 }
13 }
處理結果如下:
非數據類型不能轉換。
throw與throws的比較
1、throws出現在方法函數頭;而throw出現在函數體。
2、throws表示出現異常的一種可能性,並不一定會發生這些異常;throw則是拋出了異常,執行throw則一定拋出了某種異常對象。
3、兩者都是消極處理異常的方式(這裏的消極並不是說這種方式不好),只是拋出或者可能拋出異常,但是不會由函數去處理異常,真正的處理異常由函數的上層調用處理。
好的編程習慣:
1.在寫程序時,對可能會出現異常的部分通常要用try{...}catch{...}去捕捉它並對它進行處理;
2.用try{...}catch{...}捕捉了異常之後一定要對在catch{...}中對其進行處理,那怕是最簡單的一句輸出語句,或棧輸入e.printStackTrace();
3.如果是捕捉IO輸入輸出流中的異常,一定要在try{...}catch{...}後加finally{...}把輸入輸出流關閉;
4.如果在函數體內用throw拋出了某種異常,最好要在函數名中加throws拋異常聲明,然後交給調用它的上層函數進行處理。
捕捉異常
先講捕捉異常
1 try{
2 ……
3 }catch(Exception e){
4 ……
5 }finally{
6 ……
7 }
try{……}中放置可能會發生異常的的語句塊,如可能出現異常的函數,也可以是一般的程序語句;catch(){……}用於抓住異常,(Exception e)中Exception是異常的類型,必須是Exception(Exception是所有異常類的父類)的子類。{}定義當出現異常時的處理方法。finally{……}表示不管異常是否發生,都得進行finally{}中的處理。
在捕捉異常的try{...}語句塊中,如果出現了異常,則該語句(出現異常的語句)後的程序語句都不執行,而是跳到catch{...}語句塊中執行異常的處理。如:
1 public static void function1() throws NumberFormatException{
2 System.out.println(Double.parseDouble("abc"));
3 System.out.println("第二條語句。");
4
5 }
6
7 public static void main(String[] args) {
8 try {
9 function1();
10 } catch (Exception e) {
11 System.err.println(e.getMessage());
12 //e.printStackTrace();
13 }
14 }
結果如下,只輸出了一條錯誤提示語:
For input string: "abc"
System.out.println("第二條語句。");未執行。
如果一個函數沒有用throws進行拋異常,在調用該函數的方法也同樣可以捕捉異常。如
1 public static void function() {
2 String s = "abc";
3 System.out.println(Double.parseDouble(s));
4 }
5
6 public static void main(String[] args) {
7 try {
8 function();
9 } catch (Exception e) {
10 System.err.println("非數據類型不能轉換。");
11 //e.printStackTrace();
12 }
13 }
處理結果如下:
非數據類型不能轉換。
說明:某個函數或某段程序塊不管會不會,有沒可能拋出異常,都可以加try{...}catch{...}去捕捉它。
自定義異常
用戶可以自定義異常,新建一個異常類,讓其繼承Exception類或Exception的某個子類。然後用throw拋出自己定義的異常類對象。如:
1 public static void function() throws ParenthesisMatchingException{
2 String s = "((a+b)";
3 ParenthesisMatchingException e = new ParenthesisMatchingException("括號匹配異常!");
4 if(s.charAt(0)==‘(‘ && s.charAt(1)==‘(‘) {
5 throw e;
6 }
7 System.out.println(s);
8 }
9
10 public static void main(String[] args) {
11 try {
12 function();
13 } catch (Exception e) {
14 System.out.println(e.getMessage());
15 //e.printStackTrace();
16 }
17 }
結果如下 :
括號匹配異常!
【Java學習筆記之三十二】淺談Java中throw與throws的用法及異常拋出處理機制剖析