Javaの例外処理では,catchブロックを複数書くことがありますが,どうやらサブクラスのcatch文を先に指定しないといけないようです.
例えば次の例外クラスの継承関係を見てみます.
- ExceptionクラスのサブクラスにはRuntimeExceptionクラスがある.
- RuntimeExceptionクラスのサブクラスには次の2つのがある.
・ArithmetricException 整数を0で除算したときに例外発生
・NullPointerException null値の変数を使用したときに例外発生
次のコードは,意図的にArithmetricExceptionとNullPointerExceptionを発生させて,それをtry〜catch文で処理するコードです.
public class ExceptionTest { public static void main(String[] args) { try { // ArithmeticException System.out.println(10 / 0); //←(A) // NullPointerException int a[] = null; System.out.println(a[0]); } catch (ArithmeticException e) { //←(B) System.out.println("ArithmeticException"); } catch (RuntimeException e) { //←(C) System.out.println("RuntimeException"); } catch (Exception e) { System.out.println("Exception"); } } }
そのまま実行したときの実行結果
ArithmeticException
(A)行をコメントアウトしたときの実行結果
RuntimeException
(A)行をコメントアウトしたときの実行過程は次の通りです.
- try文の中でNullPointerExceptionが発生.
- (B)行で評価.しかし,クラスが違うので受け取れない.
- (C)行で評価.親クラスなので例外を受け取り,そのcatch文のコードを実行.
(B)行と(C)行は入れ替えても良さそうですが,この順番を入れ替えることはできません.もし入れ替えてしまうと,最初のcatch文でRuntimeExceptionのサブクラスをすべて受け取ってしまい,NullPointerExceptionのcatch文は到達不能となってしまうためです.