Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaで例外を再スローするとは?基本の意味と実装例をわかりやすく解説

Javaでは、catchブロックで捕捉した例外を、throwキーワードを使って再度投げる(再スロー)ことができます。throwキーワードは、もともと例外オブジェクトを投げるために使用されるものです。

例外の再スローには、主に以下の2つの方法があります。

1. 捕捉した例外をそのまま再スローする

catchブロックで捕捉した例外を、一切加工せずにそのまま投げ直す方法です。

try {
    int result = (arr[a])/(arr[b]);
    System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result);
}
catch(ArithmeticException e) {
    throw e;
}

2. 新しい例外でラップしてスローする(例外チェーン)

もう一つの方法は、捕捉した例外を別の新しい例外で包んで(ラップして)スローすることです。この手法は「例外チェーン」や「例外ラッピング」と呼ばれます。この方法を使うと、元の例外情報を保ちながら、抽象度の高い上位レベルの例外としてスローし直すことができます。

try {
    int result = (arr[a])/(arr[b]);
    System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result);
}
catch(ArrayIndexOutOfBoundsException e) {
    throw new IndexOutOfBoundsException();
}

サンプルプログラム

次のJavaの例では、demoMethod()内のコードがArrayIndexOutOfBoundsExceptionまたはArithmeticExceptionをスローする可能性があります。これら2つの例外を、それぞれ異なるcatchブロックで捕捉しています。

catchブロック内では、一方の例外はより上位の例外でラップして再スローし、もう一方はそのまま直接再スローしています。

import java.util.Arrays;
import java.util.Scanner;
public class RethrowExample {
    public void demoMethod() {
        Scanner sc = new Scanner(System.in);
        int[] arr = {10, 20, 30, 2, 0, 8};
        System.out.println("Array: "+Arrays.toString(arr));
        System.out.println("Choose numerator and denominator(not 0) from this array (enter positions 0 to 5)");
        int a = sc.nextInt();
        int b = sc.nextInt();
        try {
            int result = (arr[a])/(arr[b]);
            System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result);
        }
        catch(ArrayIndexOutOfBoundsException e) {
            throw new IndexOutOfBoundsException();
        }
        catch(ArithmeticException e) {
            throw e;
        }
    }
    public static void main(String [] args) {
        new RethrowExample().demoMethod();
    }
}

実行結果1

配列の範囲外の位置(124)を指定した場合、IndexOutOfBoundsExceptionがスローされます。

Array: [10, 20, 30, 2, 0, 8]
Choose numerator and denominator(not 0) from this array (enter positions 0 to 5)
124
5
Exception in thread "main" java.lang.IndexOutOfBoundsException
    at myPackage.RethrowExample.demoMethod(RethrowExample.java:17)
    at myPackage.RethrowExample.main(RethrowExample.java:23)

実行結果2

分母として値が0の要素(位置4)を指定した場合、ArithmeticExceptionがそのまま再スローされます。

Array: [10, 20, 30, 2, 0, 8]
Choose numerator and denominator(not 0) from this array (enter positions 0 to 5)
0
4
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at myPackage.RethrowExample.demoMethod(RethrowExample.java:16)
    at myPackage.RethrowExample.main(RethrowExample.java:25)

まとめ

例外の再スローは、メソッド内で発生した例外を呼び出し元に伝播させたい場合に有効なテクニックです。低レベルの例外をそのまま外部に漏らさず、アプリケーション固有の上位例外に変換したい場合は例外ラッピングを、詳細な例外情報をそのまま維持したい場合は直接の再スローを選ぶなど、目的に応じて使い分けるとよいでしょう。

  1. JavaのStringIndexOutOfBoundsExceptionとは?発生原因と対処法をわかりやすく解説

    StringIndexOutOfBoundsExceptionとはJavaにおいて、文字列(String)は一連の文字を格納するために使用され、オブジェクトとして扱われます。文字列は、java.langパッケージに含まれるStringクラスによって表現されます。文字列の作成方法は主に2つあります。1つは他のオブジェクトと同様にnewキーワードを使用する方法、もう1つはプリミティブ型のようにリテラルを直接代入する方法です。String stringObject = new String(Hello how are you); String stringLiteral = Welcome to T

  2. Javaの例外(Exception)とは?基本概念から例外処理の方法まで徹底解説

    Java開発者にとって、Javaの例外と例外処理に関する知識は必須です。 本チュートリアルでは、Javaプログラミングにおいてすべてのエンジニアが押さえておくべき基礎知識を解説します。まずは「Javaの例外とは何か」というところから始めましょう。 Javaの例外とは Javaプログラムは、実行中に何らかの問題に遭遇し、突如として強制終了することがあります。このような問題を例外(Exception)と呼びます。 優れたプログラマーは、実行時に発生し得るエラーを予測し、例外が起きた場合でもプログラムが別の経路で動作を継続できるように設計します。このような実践が例外処理(Exception Hand