|
一、異常的產生 異常是程序之中導致程序中斷的一種指令流,異常一旦出現并且沒有進行合理處理的話,那么程序就將中斷執(zhí)行。 public class Test { public static void main(String args[]) { System.out.println('1、除法計算開始。'); int result = 10 / 2; System.out.println('2、除法計算結果:' + result); System.out.println('3、除法計算結束。'); }}
運行結果:
(2)產生異常的程序 public class Test { public static void main(String args[]) { System.out.println('1、除法計算開始。'); int result = 10 / 0; // 會出現錯誤 System.out.println('2、除法計算結果:' + result); System.out.println('3、除法計算結束。'); }}
運行結果:
一旦產生異常,我們發(fā)現產生異常的語句以及之后的語句將不再執(zhí)行,默認情況下是進行異常信息的輸出,而后自動結束程序的執(zhí)行。 現在,我們要做的是:即使程序出現了異常,也要讓程序正確的執(zhí)行完畢。 二、異常的處理 如果希望程序出現異常之后程序依然可以正常的完成的話,那么就可以使用如下的格式進行異常的處理: try { 可能出現異常的語句 ;} [ catch (異常類型 異常對象) { 處理異常 ;} catch (異常類型 異常對象) { 處理異常 ;} ... ] [finally { 不管是否出現異常,都執(zhí)行此代碼 ;}]
現在,使用以上的操作處理異常處理前面除法于是出現的異常:
運行結果: 1、除法計算開始。java.lang.ArithmeticException: / by zero3、除法計算結束。
可以發(fā)現,加入了異常處理之后,程序中即使有了異常,程序也可以正常的執(zhí)行完畢,但是異常處理時的錯誤輸出信息和之前相比,出錯的信息不明確了,那么為了讓錯誤的信息更加的完整,一般都會調用printStackTrace()方法進行異常信息的打印,這個方法打印的異常信息是最完整的:
運行結果: 1、除法計算開始。java.lang.ArithmeticException: / by zero at Test.main(Test.java:5)3、除法計算結束。
此時發(fā)現,打印的信息是很完整的。 除了try…catch格式處理異常外,還可以使用try…catch..finally:
運行結果: 1、除法計算開始。2、除法計算結果:10不管是否出現異常都執(zhí)行3、除法計算結束。
但是,對于之前的程序又有了問題:現在執(zhí)行數學計算的兩個參數,都是由程序默認提供,那么如果說現在兩個計算的參數通過初始化參數傳遞呢?
這個時候,數據由外部傳送,那么就有可能出現以下幾類問題: public class Test { public static void main(String args[]) { System.out.println('1、除法計算開始。'); try { int x = Integer.parseInt(args[0]); int y = Integer.parseInt(args[1]); int result = x / y; System.out.println('2、除法計算結果:' + result); } catch (ArithmeticException e) { e.printStackTrace(); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch (NumberFormatException e) { e.printStackTrace(); } finally { System.out.println('不管是否出現異常都執(zhí)行'); } System.out.println('3、除法計算結束。'); }}
現在,程序比之前更健壯了。 三、異常的處理流程 以上已經完成了異常的基本處理,但是所有的異常都像之前那樣一條條的判斷似乎是一件不可能完成的任務,因為日后肯定會接觸到一些不常見的異常信息,那么下面就必須首先研究異常的流程和結構。 先查看兩個異常類的繼承結構:
(2)ArrayIndexOutOfBoundsException: java.lang.Object |- java.lang.Throwable |- java.lang.Exception |- java.lang.RuntimeException |- java.lang.IndexOutOfBoundsException |-java.lang.ArrayIndexOutOfBoundsException
可以發(fā)現,所有的異常類型最高的繼承類是Throwable,Throwable下有兩個子類: 通過繼承關系可以發(fā)現,在進行日后異常處理的時候是以Exception為主,并且可以形成以下的異常處理流程: (1)如果程序中產生了異常,那么JVM根據異常的類型,實例化一個指定異常類的對象; (2)如果這時程序中沒有任何的異常處理操作,則這個異常類的實例化對象將交給JVM進行處理,而JVM的默認處理方式就是進行異常信息的輸出,而后中斷程序執(zhí)行; (3)如果程序中存在了異常處理,則會由try語句捕獲產生的異常類對象; (4)與try之后的每一個catch進行匹配,如果匹配成功,則使用指定的catch進行處理,如果沒有匹配成功,則向后面的catch繼續(xù)匹配,如果沒有任何的catch匹配成功,則這個時候將交給JVM執(zhí)行默認處理; (5)不管是否有異常都會執(zhí)行finally程序,如果此時沒有異常,執(zhí)行完finally,則會繼續(xù)執(zhí)行程序之中的其他代碼,如果此時有異常沒有能夠處理(沒有一個catch可以滿足),那么也會執(zhí)行finally,但是執(zhí)行完finally之后,將默認交給JVM進行異常的信息輸出,并且程序中斷。 通過以上的分析可以發(fā)現,實際上catch捕獲異常類型的操作,就和方法接收參數是一樣的,那么按照之前所學習過的對象多態(tài)性來講,所有的異常類都是Exception的子類,那么這個時候,實際上所有的異常都可以使用Exception進行接收:
這時應該可以感受到異常處理所帶來的好處了。但是這種操作也存在一種問題:如果在一些異常處理要求嚴格的項目之中,異常必須分別處理,如果現在異常的處理要求不是很嚴格,直接編寫Exception就足夠了。 未完待續(xù)。。。 |
|
|