java異常處理

try...catch...finally我們經常在代碼中用到了,一直覺得這個東西沒有太大的用處。因爲在開發中,我們總是很堅信我們的代碼是不會出錯的。這樣說來,問題就來了,一旦我們的系統出了錯,沒有它們,系統就會崩潰,反映給用戶,用戶就不會再用這個系統。


一、Java異常


異常指不期而至的各種狀況,如:文件找不到、網絡連接失敗、空指針、類找不到、非法參數等等。異常是一個事件,它發生在異常運行期間,干擾了正常的指令流程。Java通過API中的Throwable類的衆多子類描述各種不同的異常。因此,Java異常也是異常,是Throwbale子類的實例。


Java異常類層次結構圖



從圖中我們可以看到,Throwable作爲一個類,有兩個重要的子類:


Error(錯誤):程序是無法處理的,一旦遇到,系統崩潰,無法繼續運行,表示運行應用程序中較嚴重的問題。


Exception(異常):程序本身可以進行處理的異常。一般可以分爲兩類:Io流出和運行異常。


二、處理異常機制


在Java應用程序中,異常處理機制:拋出異常,捕捉異常。


拋出異常:當一個方法出現錯誤引發宜昌市,方法創建異常對象並交付運行時系統,異常對象中包含了異常類型和異常出現時的程序狀態等異常信息。通常我們用throw將異常拋給調用它的方法。


捕捉異常:在方法拋出一場之後,運行時系統將轉爲尋找合適的異常處理器。在方法拋出異常之後,運行時系統將轉爲尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發生時依次存留在調用棧中的方法的集合。當異常處理器所能處理的異常類型與方法拋出的異常類型相符時,即爲合適 的異常處理器。運行時系統從發生異常的方法開始,依次回查調用棧中的方法,直至找到含有合適異常處理器的方法並執行。當運行時系統遍歷調用棧而未找到合適 的異常處理器,則運行時系統終止。同時,意味着Java程序的終止。


對於運行時異常、錯誤或可查異常,Java技術所要求的異常處理方式有所不同。


由於運行時異常的不可查性,爲了更合理、更容易地實現應用程序,Java規定,運行時異常將由Java運行時系統自動拋出,允許應用程序忽略運行時異常。


對於方法運行中可能出現的Error,當運行方法不欲捕捉時,Java允許該方法不做任何拋出聲明。因爲,大多數Error異常屬於永遠不能被允許發生的狀況,也屬於合理的應用程序不該捕捉的異常。


 對於所有的可查異常,Java規定:一個方法必須捕捉,或者聲明拋出方法之外。也就是說,當一個方法選擇不捕捉可查異常時,它必須聲明將拋出異常。


一個方法所能捕捉的異常,一定是java代碼在某處拋出的異常。簡單地說,異常總是先被拋出,後被捕捉的。


一個方法中拋出的任何異常都必須使用throws字句。


1、捕捉異常


通常使用try-catch或者try-catch-finally語句實現。


(1)、try-catch


實例:


  1. public class TestException {    
  2.     public static void main(String[] args) {    
  3.         int[] intArray = new int[3];    
  4.         try {    
  5.             for (int i = 0; i <= intArray.length; i++) {    
  6.                 intArray[i] = i;    
  7.                 System.out.println("intArray[" + i + "] = " + intArray[i]);    
  8.                 System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值:  "    
  9.                         + intArray[i] % (i - 2));    
  10.             }    
  11.         } catch (ArrayIndexOutOfBoundsException e) {    
  12.             System.out.println("intArray數組下標越界異常。");    
  13.         } catch (ArithmeticException e) {    
  14.             System.out.println("除數爲0異常。");    
  15.         }    
  16.         System.out.println("程序正常結束。");    
  17.     }    
  18. }    

上面的代碼中捕獲兩個錯誤:除數爲0和數組下標越界異常。運行結果:


intArray[0] = 0

intArray[0]模 -2的值:  0

intArray[1] = 1

intArray[1]模 -1的值:  0

intArray[2] = 2

除數爲0異常。

程序正常結束。



我們運行就會發現當捕捉到第一個錯誤的時候,系統將不再執行try之後的代碼,運行先捕捉到除數爲0的錯誤,因此,而後的處理結束,就以爲這整個try-catch語句結束。


Java通過異常類描述異常類型,異常類的層次結構如圖1所示。對於有多個catch子句的異常程序而言,應該儘量將捕獲底層異常類的catch子 句放在前面,同時儘量將捕獲相對高層的異常類的catch子句放在後面。否則,捕獲底層異常類的catch子句將可能會被屏蔽。


(2)、try-catch-finally


不管catch有沒有異常捕獲,finally都是會運行的。


圖示try-catch-finally語句的執行:



2、拋出異常


(1)、throws拋出異常


如果一個方法可能會出現異常,但沒有能力處理這種異常,可以在方法聲明處用throws子句來聲明拋出異常。例如汽車在運行時可能會出現故障,汽車本身沒辦法處理這個故障,那就讓開車的人來處理。


throws語句用在方法定義時聲明該方法要拋出的異常類型,如果拋出的是Exception異常類型,則該方法被聲明爲拋出所有的異常。多個異常可使用逗號分割。throws語句的語法格式爲:


  1. methodname throws Exception1,Exception2,..,ExceptionN    
  2. {    
  3. }   


使用throws關鍵字將異常拋給調用者後,如果調用者不想處理該異常,可以繼續向上拋出,但最終要有能夠處理該異常的調用者。


一般,我們使用異常,將異常拋給UI,通過Error頁面,進行處理,這樣給用戶體驗會好一些。


(2)、throw拋出異常


throw通常出現在函數體中,用來拋出一個Throwable類型的異常。程序會在throw語句會立即終止,它之後的代碼是不會執行的。


  1. <span style="font-family:KaiTi_GB2312;font-size:18px;">package Test;    
  2. import java.lang.Exception;    
  3. public class TestException {    
  4.     static int quotient(int x, int y) throws MyException { // 定義方法拋出異常    
  5.         if (y < 0) { // 判斷參數是否小於0    
  6.             throw new MyException("除數不能是負數"); // 異常信息    
  7.         }    
  8.         return x/y; // 返回值    
  9.     }    
  10.     public static void main(String args[]) { // 主方法    
  11.         int  a =3;    
  12.         int  b =0;     
  13.         try { // try語句包含可能發生異常的語句    
  14.             int result = quotient(a, b); // 調用方法quotient()    
  15.         } catch (MyException e) { // 處理自定義異常    
  16.             System.out.println(e.getMessage()); // 輸出異常信息    
  17.         } catch (ArithmeticException e) { // 處理ArithmeticException異常    
  18.             System.out.println("除數不能爲0"); // 輸出提示信息    
  19.         } catch (Exception e) { // 處理其他異常    
  20.             System.out.println("程序發生了其他的異常"); // 輸出提示信息    
  21.         }    
  22.     }    
  23.     
  24. }    
  25. class MyException extends Exception { // 創建自定義異常類    
  26.     String message; // 定義String類型變量    
  27.     public MyException(String ErrorMessagr) { // 父類方法    
  28.         message = ErrorMessagr;    
  29.     }    
  30.     
  31.     public String getMessage() { // 覆蓋getMessage()方法    
  32.         return message;    
  33.     }    
  34. } </span>  

要注意的是,throw 拋出的只能夠是可拋出類Throwable 或者其子類的實例對象。


如果拋出了檢查異常,則還應該在方法頭部聲明方法可能拋出的異常類型。該方法的調用者也必須檢查處理拋出的異常。


總結:


異常在程序中是不可以被取代的,更不能不寫,這是很危險的一件事情,異常體現了一個程序員的專業性,更能體現一個程序員的全局觀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章