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` `教學`