DEV Community

TANIAOKA, Akihiro
TANIAOKA, Akihiro

Posted on • Updated on

10章7

このJavaコードを解析して、なぜ答えがB(「10が表示される」)なのかをコメントを付けて説明します。

public class Main {
    public static void main(String[] args) {
        // sampleメソッドから返される値をresultに格納し、それを出力する
        int result = sample();
        System.out.println(result); // コンソールにresultの値を出力する
    }

    private static int sample() {
        int val = 0; // 初期値としてvalに0を設定

        try {
            // 配列を初期化する
            String[] array = {"A", "B", "C"};
            // 存在しないインデックス(3)にアクセスしようとするため、ArrayIndexOutOfBoundsExceptionが発生する
            System.out.println(array[3]);
        } catch (RuntimeException e) {
            // ArrayIndexOutOfBoundsExceptionはRuntimeExceptionのサブクラスであるため、このブロックが実行される
            val = 10; // valの値を10に設定する
            return val; // valの値(10)を返してメソッドを抜ける
            // しかし、実際にメソッドから抜ける前にfinallyブロックが実行される
        } finally {
            // finallyブロックはtry-catchブロックの終了後、必ず実行される
            val += 10; // valの値に10を加算する(この時点でvalは20になる)
            // ただし、この加算は既にスタックに積まれたreturn値(10)には影響しない
        }
        // finallyブロックにreturnがないため、ここに到達することはない
        // 実際にメソッドから抜ける際にはcatchブロックで積まれたreturn値(10)が使用される
                return val;
    }
}
Enter fullscreen mode Exit fullscreen mode

このプログラムのポイントは、try ブロックで意図的に ArrayIndexOutOfBoundsException を発生させることにあります。この例外は RuntimeException のサブクラスであり、catch ブロックで捕捉されます。catch ブロック内で val10 を代入し、その値を return しています。

しかし、finally ブロックは例外が発生しても、しなくても、return 文が実行される前に必ず実行されます。したがって、finally ブロック内で val10 が加えられ、val20 になります。ただし、これは変数 val の値を変更するだけであり、catch ブロックでリターンされた値(10)には影響しません。これはJavaの仕様であり、return 文によってメソッドからの戻り値が既に確定していた場合、finally ブロックの操作は戻り値に影響を与えません。

したがって、メソッド sample10 を返し、main メソッドはこの値を受け取ってコンソールに出力するため、結果として「10が表示される」のが正しいです。

Top comments (0)