マイナー・マイナー

隠れた名作の発掘が生きがい。

Javaの例外処理において複数のcatchブロックを使用する際に気をつけること


スポンサードリンク

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)行をコメントアウトしたときの実行過程は次の通りです.

  1. try文の中でNullPointerExceptionが発生.
  2. (B)行で評価.しかし,クラスが違うので受け取れない.
  3. (C)行で評価.親クラスなので例外を受け取り,そのcatch文のコードを実行.


(B)行と(C)行は入れ替えても良さそうですが,この順番を入れ替えることはできません.もし入れ替えてしまうと,最初のcatch文でRuntimeExceptionのサブクラスをすべて受け取ってしまい,NullPointerExceptionのcatch文は到達不能となってしまうためです.