019 例外と例外処理(例外の伝播と再スロー) 020 解答例

public class CustomExceptionPropagationExample {
    public static void main(String[] args) {
        try {
            processInput();
        } catch (CustomInputException e) {
            System.out.println("メインメソッド: " + e.getMessage());
        }
    }

    static void processInput() throws CustomInputException {
        try {
            // ユーザーからの入力を処理するコード(例外が発生する可能性がある箇所)
            // ここでは例として ArithmeticException を発生させますが、実際のコードは入力処理に関連するものに置き換えてください。
            int result = 5 / 0;  // 例外が発生する可能性のある箇所
        } catch (ArithmeticException originalException) {
            // ArithmeticExceptionを捕捉し、CustomInputExceptionに変換して再スローする
            throw new CustomInputException("入力処理中にエラーが発生しました", originalException);
        }
    }
}

class CustomInputException extends Exception {
    // 独自例外クラスの宣言

    // コンストラクタにメッセージと原因となる例外を受け取り、親クラスのコンストラクタに渡す
    public CustomInputException(String message, Throwable cause) {
        super(message, cause);
    }
}

この例では、processInput メソッド内で ArithmeticException が発生した場合に、それを CustomInputException に変換して再スローしています。 CustomInputException のコンストラクタは、メッセージと原因となる例外を受け取り、親クラスのコンストラクタに渡しています。これにより、呼び出し元で CustomInputException をキャッチした場合に、詳細なエラー情報(メッセージと原因)を取得できます。

例外の伝播と独自例外クラス

「例外の伝播」とは、メソッド内で発生した例外が、そのメソッドを呼び出した側に伝わるプロセスを指します。メソッド内で例外が発生すると、そのメソッドが呼び出された階層で例外が捕捉されない場合、例外は上位の呼び出し階層に伝播します。この伝播のプロセスにおいて、メソッド内で発生した例外を独自の例外クラスに変換して再スローすることができます。

以下は、例外の伝播と独自例外クラスを使用した解説です。

例外の伝播とは?

例外が発生すると、その例外は現在のメソッド内でキャッチされるか、それができない場合は呼び出し元のメソッドに伝播します。伝播のプロセスでは、呼び出し階層を遡りながら例外が伝わります。このとき、メソッド内で発生した例外を捕捉して新しい独自の例外クラスに変換して再スローすることができます。

独自例外クラスの使用

独自の例外クラスを作成することで、特定の状況やエラーに対応するための詳細な情報を提供できます。また、独自の例外クラスには標準の Exception クラスを拡張することが一般的です。

具体例

以下の例では、processData メソッド内で発生した例外を DataProcessingException として捕捉し、それを再度 CustomException に変換して再スローします。

public class ExceptionPropagationExample {

    public static void main(String[] args) {
        try {
            processData();
        } catch (CustomException e) {
            System.out.println("メインメソッド: " + e.getMessage());
            System.out.println("原因: " + e.getCause().getMessage());
        }
    }

    static void processData() throws CustomException {
        try {
            // データ処理を試みる(例外が発生する可能性のある箇所)
            int result = divideByZero();
        } catch (ArithmeticException originalException) {
            // ArithmeticExceptionを捕捉し、DataProcessingExceptionに変換して再スローする
            throw new DataProcessingException("データ処理中にエラーが発生しました", originalException);
        }
    }

    static int divideByZero() {
        // 0で割り算を試みる
        return 5 / 0;
    }
}

class CustomException extends Exception {
    // 独自例外クラスの宣言

    // コンストラクタにメッセージと原因となる例外を受け取り、親クラスのコンストラクタに渡す
    public CustomException(String message, Throwable cause) {
        super(message, cause);
    }
}

class DataProcessingException extends CustomException {
    // データ処理用の独自例外クラスの宣言

    // コンストラクタにメッセージと原因となる例外を受け取り、親クラスのコンストラクタに渡す
    public DataProcessingException(String message, Throwable cause) {
        super(message, cause);
    }
}

この例では、DataProcessingExceptionCustomException を継承しており、processData メソッドで発生した ArithmeticExceptionDataProcessingException に変換して再スローしています。そして、main メソッドでこの例外を捕捉し、詳細なエラーメッセージと元の例外のメッセージを表示しています。

「019 例外と例外処理」問題集リスト