DEV Community

TANIAOKA, Akihiro
TANIAOKA, Akihiro

Posted on

10章3

了解しました。こちらのJavaコードにコメントを追加し、なぜ選択肢E「コンパイルエラーが発生する」が正しいのかを説明します。

// SampleExceptionというカスタム例外クラスを定義しています。
public class SampleException extends Exception {}

// SampleExceptionから派生したSubSampleExceptionというカスタム例外クラスを定義しています。
public class SubSampleException extends SampleException {}

// メインクラスです。
public class Main {
    // Javaアプリケーションのエントリーポイントであるmainメソッドです。
    public static void main(String[] args) {
        try {
            // sample()はSampleExceptionをスローするため、次の行は実行されません。
            sample();
            // したがって、sub()メソッドは呼び出されません。
            sub();
        } 
        // ここでSampleException(またはそのサブクラス)をキャッチします。
        catch (SampleException e) {
            // SampleExceptionがキャッチされたら、"A"を出力します。
            System.out.println("A");
        } 
        // ここでSubSampleExceptionをキャッチしようとしていますが、
        // このブロックは到達不能です。なぜならSubSampleExceptionはSampleExceptionの
        // サブクラスであり、既に上のcatchブロックで捕捉されてしまうからです。
        // Javaコンパイラはこのブロックが到達不能であると判断し、コンパイルエラーを発生させます。
        catch (SubSampleException e) {
            // コンパイルエラーが発生するため、この行は決して実行されません。
            System.out.println("B");
        }
    }

    // SampleExceptionをスローするsampleメソッドです。
    private static void sample() throws SampleException {
        throw new SampleException();
    }

    // SubSampleExceptionをスローするsubメソッドです。
    private static void sub() throws SubSampleException {
        throw new SubSampleException();
    }
}
Enter fullscreen mode Exit fullscreen mode

Javaでは、catchブロックを配置するときには、最も具体的な例外タイプから順に捕捉するようにする必要があります。つまり、SubSampleExceptionのようなサブクラスの例外を先に捕捉し、その後でSampleExceptionのようなスーパークラスの例外を捕捉するべきです。

このコードでは、SampleExceptionを先に捕捉するため、SubSampleExceptionを捕捉するブロックが到達不可能となります。このような到達不可能なコードはコンパイラによってエラーとして報告されます。したがって、コンパイラはこのコードをコンパイルできず、結果としてコンパイルエラー(選択肢E)が発生するのです。

追記

コンパイルエラーを回避するには、catchブロックの順序をサブクラスの例外が先になるように変更する必要があります。最も特定の例外タイプ、つまりサブクラスから始めて、その後により一般的な例外タイプ、スーパークラスの例外をキャッチするようにします。

修正されたコードは以下のようになります:

public class Main {
    public static void main(String[] args) {
        try {
            sample();
            sub();
        } 
        // サブクラスの例外を先にキャッチします。
        catch (SubSampleException e) {
            // SubSampleExceptionがキャッチされたら、"B"を出力します。
            System.out.println("B");
        }
        // その後に、より一般的な例外をキャッチします。
        catch (SampleException e) {
            // SampleExceptionがキャッチされたら、"A"を出力します。
            System.out.println("A");
        }
    }

    private static void sample() throws SampleException {
        throw new SampleException();
    }

    private static void sub() throws SubSampleException {
        throw new SubSampleException();
    }
}
Enter fullscreen mode Exit fullscreen mode

この変更によって、SubSampleExceptionをキャッチするcatchブロックが先にあり、その後にSampleExceptionをキャッチするcatchブロックが配置されています。これにより、コンパイルエラーは発生せず、特定の例外が適切にキャッチされるようになります。

Top comments (0)