Java --- Exception (例外處理) === ## Event 即使code可以通過compiler仍會有一些runtime中的error,較輕微的error可以被Runtime Handler接管解決,稱為 **runtime exception** (e.g. 除0,Array存取超出範圍),而不能被解決的稱為**error** (e.g. 作業系統毀損,磁碟壞軌). 但通常若被Runtime Handler接管處理後,程式會被強制停止,而data若沒有事先做處理則會全部流失,所以就是以下要提及的==自己處理exception== 來確保程式及時遭遇runtime exception 仍有對應的處理方式讓程式不會被中斷. ## Java例外的種類 在java的世界中所有東西都是object,exception亦是,所以當exception發生時,就會產生一個對應的**例外類別的物件** ,再對特定例外物件做特定處理,==例外物件可分**兩類**== . * ### Java內建的例外類別 內建的例外類別有很多,而所有類別都繼承**Throwable** ,繼承後又可分為兩類 **Exception class** , **Error class** ,分別處理,通常命名方式就可以得知是處理哪一類型的問題,*Example:IOException* 是對於IO可能會引發的exception來處理 * ### 自定義的例外類別 內建類別通常是關心程式是否可以**正常運行** ,但常常我們會需要處理**特定狀況** 因而使用自定義的例外處理. 自定義例外類別==至少必須繼承Throwable class== ,但通常我們不會想處理error,所以==一般會繼承exception class== 為Throwable的子類別. For instance: ```java class myException extends Exception { public myException() { super(); } public myException(String content) { super(content); } public showMsg() { System.out.println(getMessage()); //getMessage來自父類別Exception的method } } ``` ## 引發例外的方式 有**兩種** 方式觸發 * ### 自動觸發 當內建例外條件中任意一種狀況發生時,會自動產生例外物件,並由Runtime Handler來菊定如何處理,通常會**中斷程式並顯示問題** For instance: ```java= public class autoT { public static void main(String arg[]) { int k =0; int q =1000; int foo = q / k; System.out.println(foo); } } ``` Output: ```= java -cp ./classes autoT Exception in thread "main" java.lang.ArithmeticException: / by zero at autoT.main(autoT.java:8) ``` *中斷程式並給予提示* * ### 自行觸發 -- throw Syntax: ==throw new Exception class;== Example: ```java throw new ClassCastException("Class transform error"); ``` 但丟出例外仍未被處理,欲處理即是接下來要介紹的**try..catch..finally語法** . --- ## 處理例外 *Syntax*: ```java try { ... } catch(Exception e) { ... } finally { ... } ``` * ### try{...} 此區將有可能會發生例外的地方,throw出例外物件 *Note:try區塊自己為一個生命週期,即在這裡宣告的變數在離開try後就被回收,catch及finally區塊亦是.* For instance: ```java if(num >1000 || num <0) throw new myException("Overflowing"); //myException為自定義例外class System.out.println("if the exception didn't occur,then print this line,otherwise this line will be skipped.") ``` * ### catch(){...} 此區接收丟出的例外物件,並針對不同例外做不同處理,所以可以有多個catch區塊. *Note:仍可能有未被捕捉到的例外,仍有可能觸發runtime handler處理* For instance: ```java catch(myException e) { e.showMsg(); //determine how to handle the exception. } catch(Exception e) { //anotehr exception class System.out.println(e.getmessage()); //indicate that there may be multiple catch blocks. } ``` * ### finally{...} 只要有進try區塊,無論中間發生什麼事一定會進finally,即使要被runtime handler接收,也會在接收前先執行finally區塊. For instance: ```java public class autoT { public static void main(String arg[]) { int k =0; int q =1000; try { int foo = q / k; } finally { System.out.println("finallly innnnn"); } } } ``` Output: ```= java -cp ./classes autoT finallly innnnn Exception in thread "main" java.lang.ArithmeticException: / by zero at autoT.main(autoT.java:10) ``` Line 2:執行finally區塊 Line 3:runtime handler處理exception. 因為==通常此區塊被拿來清除狀態== ,確保之後不會被影響,例如在IO方面,需要最後做close動作,放在這邊就很好. --- ## throws 如果class的method可能會引某種exception,但又不想在function內解決,而是留給使用此method的使用者決定如何處理exception,**即在method後加上關鍵字throws** . For example: ```java public static int parseInt(String s) throws NumberFormatException ``` 欲使用加上throws的method則==使用者必須要給出如何處理exception== ,否則compiler不會過. For example: ```java public static void main(String arg[]) { int foo ; try { foo = parseInt(varTest); //supposed varTest is an unknown variable } catch(NumberFormatException e) { e.getmessage(); } finally { ; } } ``` ###### tags: `java` `教學`