轉載:http://blog.csdn.net/luoweifu/article/details/10721543 我進行了一些加工,不是本人原創但比原博主要更完善~ 淺談Java異常 以前雖然知道一些異常的處理,也用過一些,但是對throw和throws區別還是有不太清楚。今天用實例測試一下 異常 ...
轉載:http://blog.csdn.net/luoweifu/article/details/10721543 我進行了一些加工,不是本人原創但比原博主要更完善~
淺談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)首先創建自定義異常類,語法格式:自定義異常類名 extends Exception。
2)在方法中通過關鍵字throw拋出異常對象。
3)若是在當前拋出異常的方法中處理異常,可以用try-catch語句捕獲並處理;若不是,在方法的聲明處通過關鍵字throws指明要拋出給方法調用的異常。
4)在出現異常方法的調用中捕獲並處理異常
如:
1 package packageone; 2 3 //自定義異常類 4 class MyException extends Exception{ 5 public MyException(String s){ 6 super(s); 7 } 8 } 9 10 /* 11 * 設計類Number,類中有除法計算方法。使用自定義異常類 12 */ 13 class Number{ 14 public int divition(int num1,int num2) throws MyException { 15 if (0==num2) { 16 throw new MyException("分母不能為零!"); 17 } 18 return (num1/num2); 19 } 20 } 21 //測試自定義異常類 22 public class ExceptionTest{ 23 public static void main(String[] args) { 24 Number n = new Number(); 25 try { 26 System.out.println("自定義兩個數的商的結果為:"+n.divition(12, 0)); 27 } catch (MyException e) { 28 System.out.println(e.getMessage()); 29 e.printStackTrace(); 30 } 31 } 32 }
處理結果如下: 分母不能為零!
packageone.MyException: 分母不能為零!
at packageone.Number.divition(ExceptionTest.java:16)
at packageone.ExceptionTest.main(ExceptionTest.java:26)