Java Exception handle

20 April 2020

OOP - Java Exception handle

Exception不要太常丟,只有在必要時丟,其他時間用if/else處理
用來處理special case的input
流程:

  1. Exception throw : library或code發現有些不正常的行為,產生exception signal
  2. 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,但最好都要有兩個特徵

  1. getMessage method來取得錯誤訊息
  2. constructor吃一個String當參數來存錯誤的description(或throw的訊息)
  3. 最好是derived class of Exception class
  4. 通常derived exception class不用寫太多,大多可以用繼承的就好,但constructor很重要
  5. 通常constructor要有兩個,一個是沒有parameter的(default message of exception),一個有string參數的
  6. 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

Reference

java throw self-defined exception