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

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

    static void performOperation() throws CustomException {
        try {
            // 何らかの操作を試みる
            // 例外が発生した場合
            int result = 10 / 0; // 例外を発生させるためのダミーコード
        } catch (Exception e) {
            // カスタム例外として再スローし、元の例外をチェーンするコードを追加
            CustomException customException = new CustomException("操作中にエラーが発生しました");
            customException.initCause(e); // 元の例外を設定
            throw customException;
        }
    }
}

class CustomException extends Exception {
    // カスタム例外クラスの宣言
    public CustomException(String message) {
        super(message);
    }
}

この例では、performOperation メソッド内で何らかの操作を試みて例外が発生すると仮定しています。その例外を CustomException として再スローし、元の例外を initCause メソッドを使用してチェーンしています。このようにすることで、main メソッドで CustomException とその原因の元の例外を取得できます。

再スローとチェーン

「再スローとチェーン」は、例外処理において、捕捉した例外を再度スローすることと、その際に元の例外を新しい例外の原因として設定することを指します。これにより、より詳細な情報を保持しつつ、例外を上位の呼び出し元に伝えることができます。

再スローとチェーンの手順

  1. 例外の捕捉: 例外が発生する可能性のあるコードを try-catch ブロックで囲み、例外が発生した場合にそれを捕捉します。
  2. 新しい例外の作成: もし、上位の呼び出し元に詳細な情報を提供する必要がある場合、新しい例外クラスを作成します。このクラスは通常、Exception クラスを継承しています。
  3. 例外の再スローとチェーン: catch ブロック内で、捕捉した例外を新しい例外として再スローします。そして、initCause メソッドを使用して、新しい例外の原因として捕捉した元の例外を設定します。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

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

    static void readFile(String fileName) throws CustomFileException {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(fileName));
            // ファイルからテキストを読み取るコード
        } catch (IOException e) {
            // ファイルが見つからない場合、新しい例外を作成して原因としてIOExceptionを設定し再スロー
            CustomFileException customException = new CustomFileException("ファイル読み取り中にエラーが発生しました");
            customException.initCause(e);
            throw customException;
        }
    }
}

class CustomFileException extends Exception {
    // カスタム例外クラスの宣言
    public CustomFileException(String message) {
        super(message);
    }
}

この例では、readFile メソッド内でファイル読み取り時に発生する IOException を捕捉し、新しい例外 CustomFileException として再スローしています。そして、initCause メソッドを使用して、CustomFileException の原因として捕捉した IOException を設定しています。これにより、main メソッドで CustomFileException とその原因の IOException を取得できます。

再スローとチェーンは、例外処理をより情報豊かで柔軟なものにする重要な手法です。メソッド内で発生した例外を捕捉して、新しい例外にラップし、その新しい例外に原因となる例外をチェーンさせることで、呼び出し元でより詳細な情報を取得できるようになります。

この手法を使用することで、異なる階層で発生した例外を連結し、階層ごとに適切な例外クラスを作成することができます。これにより、エラーの発生源を正確に特定し、より効果的に例外を処理することが可能です。ただし、注意が必要で、適切な情報を保持しつつ冗長にならないように設計することが重要です。

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