Java Exception handle
20 April 2020
OOP - Java Exception handle
Exception不要太常丟,只有在必要時丟,其他時間用if/else處理
用來處理special case的input
流程:
- Exception throw : library或code發現有些不正常的行為,產生exception signal
- exception handle : 負責接收exception signal,並來這段code看要怎麼處理
try-throw-catch
try
裡面放要執行的code
throw
產生unusual behavior時觸發(大部分狀況library會處理這部分,我們只要catch就好,只有自己寫的method要自己寫throw),Exception本身是一個class,他有一個constructor會吃一個String當參數
throw new Exception_class(String description)
throw new Exception(".....")
catch(Exception e)
有一個參數,以exception為parameter(block parameter),並在throw以後在這裡執行接續動作
- catch的block parameter的type為exception class,可以宣告為特定的exception class,那這個catch就只有在throw該特定的exception class時可以執行,也可以直接宣告Exception,那就是只要是exception,這個class就可以執行
一般用法
while (!done){
try{
...
done = true
}
catch(Exception e){..., e.getMessage()來取得error的訊息(就是throw error得到的description)}
}
EX :
import java.util.InputMismatchException; //一個exception class
while(!done){
try{...;done = true}
catch(InputMistmatchException e){...}
}
Exception class
- 有很多種,Exception只是其中一種(root class of all other exception class),
- Exception class在java.lang,所以不用特別import,本來就會import進來
self define exception class
也可以自己產生一個Exception class,定義更多特定exception幫忙debug,但最好都要有兩個特徵
- getMessage method來取得錯誤訊息
- constructor吃一個String當參數來存錯誤的description(或throw的訊息)
- 最好是derived class of Exception class
- 通常derived exception class不用寫太多,大多可以用繼承的就好,但constructor很重要
- 通常constructor要有兩個,一個是沒有parameter的(default message of exception),一個有string參數的
- constructor配合super先建立base class
public class test extends Exception{
public test(){
super("division by zero");
...
}
public test(String msg){
super(msg);
}
}
other type message
除了string外,也可以在自己建立的exception class有其他type當message,像是string type 那在constructor時就要自己賦予依樣一種default的,另一種是throw傳進來的 然後要寫一個accessor getInt之類的method,讓exception可以retrieve這個額外的type的message
public class test extends Exception{
private int Intmsg;
test(){
super("test"); //error message to base class
Intmsg = 0
}
test(int a){
super("tset1");
Intmsg = a;
}
getInt(){return Intmsg;}
}
throw new test(3);
multiple catch
一個try block可以丟很多Exception,
所以可以宣告多個catch有不同的參數Exception,來決定要丟到哪個catch執行
如果有多個catch的Exception條件符合的話,會選擇最早符合的那個catch block走
如有某個throw exception除了catch(特定exception)外還有catch(Exception e)符合,會選擇最先符合那個block走,所以catch順序很重要
exception in method
throw exception的部分依定要再try block
對於會throw Exception的method,再跑這個method的函示、主程式寫try block
try{
某個method會throw exception,這樣即可
}
catch{...}
throw clause
Catch or Declare rule
Exception的處理要either要在method裡有throw/catch
clause且method外表明有哪些exception交給外面catch
- checked exception : 符合catch or declare rule
- unchecked exception : 不符合這個rule的exception
有些method會丟exception,但是自己method內沒有catch來處理exception,那就要在宣告此method時標明這method有哪些可能的exception,並在要呼叫此method的地方做這些exception的try catch,沒做的話可能會compile error
public void test() throws DisionByZeroException
如果再method內有標明catch該Exception的block,就不用標明該Exception
這樣的做法在假設method B呼叫A,B就要負責處理ExpB,ExpC的catch,這樣將責任地回下去,
如果有C呼叫B,那C就要負責catch,所以B就要在呼叫A的地方try,catch
public void A() throws ExpB,ExpC{...}
public void B(){
A();
}
如上例,假設ExpB,ExpC真的發生了,那A method就會停住不跑
Exceptions no need to catch(unchecked exception)
有些catch不受 catch or declare rule限制
有些exception可以catch也可以不catch,發生時通常代表有程式錯誤
EX : runtime error, ArrayIndexOutOfBoundsException(runtime exception下面的一個class)
在runtime error exception class下面的exception不用catch
Error這個class下面的exception也不用catch
Derived class throw clause
如果子類別要override throw clause的method,那宣告的throw clause要跟base class依樣或者是他的subset,不能增加throw clause。(因為還是屬於base class,也能upcast)
finally
不論有沒有丟exception,都會執行的block try{} catch(e){} finally{}
assert
來自AssertionError class,是Error class的derived class,不用catch,也可以catch,因此如果有assert fail的話程式會停,當然也可以catch來handle,會丟AssertionError