未来エンジニア養成所Blog

プログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】例外処理 Part2

title

前回に引き続き例外処理の解説をします。

前回の記事はこちら phoeducation.work


複数のcatchブロックの定義

try-catch構文を使って例外処理を記述する場合、例外処理を記述する部分であるcatchブロックを複数記述することが可能です。

その場合、最初のcatchブロックで受け取れない例外は次のcatchブロックで受け取ります。

もしどのcatchブロックでも受け取れない場合は、プログラムは例外処理を行うことができず、中断してしまいます。

title


catchブロックを複数記述する場合は、サブクラスの例外から先に記述しなければなりません。

もし最初にスーパークラスの例外を記述してしまうと、すべての例外処理は最初のcatchブロックで受け取られることになり、その次に記述したcatchブロックに制御が移ることはなくなるので、「到達不能」としコンパイルエラーになります。

title


【複数のcatchブロックの記述】

public class ExceptionSample05 {
    public static void main(String[] args){
        String str = null;
        try{
            System.out.println(str.length());
        }catch(NullPointerException e){
            System.out.println("NullPointerException発生");
        }catch(RuntimeException e){
            System.out.println("RuntimeException発生");
        }catch(Exception e){
            System.out.println("Exception発生");
        }
    }
}


実行結果

NullPointerException発生


3行目のString型の変数strにはnullが代入されていますので、5行目のstr.length()を実行するとnullを参照したというNullPointerExceptionが発生し、6行目のcatchブロックで例外オブジェクトを受け取り、7行目が実行されてプログラムが終了します。

tryブロックで実行した処理が、6行目のcatchブロックで処理できなった時に8行目は10行目のcatch文で受け取れるようになっています。

このcatchブロックに記述されている例外クラスの順番は、NullPointerException→RuntimeException→Exceptionの順になっており、サブクラスから先に記述されているので、この記述に問題はありません。

title


マルチcatchブロックの定義

JDK6までは、継承関係のない複数の例外クラスをcatchするには、そのクラスごとにcatchブロックを定義する必要がありました。

JDK7からマルチcatchという機能が追加され、複数の例外クラスをまとめてキャッチできるようになりました。

その際には、各例外クラスを「|」で区切ります。


【継承関係のないcatchブロックの定義】

public class ExceptionSample06 {
    public static void main(String[] args){
        String str = null;
        try {
            int cnt = str.length();
            int i = Integer.parseInt("ABC");
        }catch(NullPointerException e){
            System.out.println(e.getMessage());
        }catch(NumberFormatException e){
            System.out.println(e.getMessage());
        }
    }
}


実行結果

null


5行目をコメントにして再度実行します。

For input string: "ABC"


3行目のString型の変数strにはnullが代入されていますので、5行目のstr.length()を実行すると7行目のNullPointerException例外クラスでキャッチします。

6行目ではInteger.parseInt()の引数に数値に変換できない文字列を指定しているので9行目のNumberFormatException例外クラスでキャッチします。

JDK6までは、このように継承関係のない例外クラスは、それぞれにcatchブロックを記述しなければなりませんでした。

なお、8、10行目に指定されている、getMessage()メソッドはThrowableクラスに定義されており、オブジェクトの詳細メッセージ文字列を返します。


【継承関係のないcatchブロックの定義】

public class ExceptionSample07 {
    public static void main(String[] args){
        String str = null;
        try {
            int cnt = str.length();
            int i = Integer.parseInt("ABC");
        }catch(NullPointerException | NumberFormatException e){
            System.out.println(e.getMessage());
        }
    }
}


実行結果

null


5行目をコメントにして再度実行します。

For input string: "ABC"


JDK7より継承関係のない例外クラスをcatchブロックに|で区切って記述できるようになりました。

catch(NullPointerException | NumberFormatException e)


「例外処理 Part3」へ続きます。 phoeducation.work


参考図書



独学で挫折しそうになったら、オンラインプログラミングスクール
未来エンジニア養成所Logo



あわせて学習したい

phoeducation.work phoeducation.work