4

サブクラスのメソッドは、親クラスのメソッドをオーバーライドし、親クラスのメソッドが例外をスローしないときに実行時例外をスローできますか?このようなもの:

class X { public void foo() { System.out.print("X "); } }

public class SubB extends X {
    public void foo() throws RuntimeException {
        super.foo();
        if (true) 
            throw new RuntimeException();
        System.out.print("B ");
    }

    public static void main(String[] args) {
        new SubB().foo();
    }
}
4

1 に答える 1

3

はい。ランタイム例外はメソッドシグネチャの一部ではないためです。(それらを追加することはできますが、コンパイラーは気にしません。それらは単なるドキュメントです。)

理論的根拠は、RuntimeExceptionsは通常、NPEや配列の範囲外などのプログラマーエラーであるため、チェックされた例外が制限される方法でそれらを制限しようとすることは意味がないということだと思います。JVMはそのような種類の保証を行わないため、このメソッド(およびそれをオーバーライドするメソッド)がNullPointerExceptionをスローすることは決してないというルールを作成することはできません。

例外のコンパイル時チェックの下のJava言語仕様では、次のように述べています。

チェックされていない例外クラス(§11.1.1)は、コンパイル時のチェックから除外されます。

チェックされていない例外クラスのうち、エラークラスはプログラムの多くのポイントで発生する可能性があり、それらからの回復が困難または不可能であるため、免除されます。そのような例外を宣言するプログラムは、無意味に散らかっています。洗練されたプログラムは、これらの状態のいくつかをキャッチして回復を試みることをまだ望んでいる可能性があります。

チェックされていない例外クラスのうち、実行時例外クラスは免除されます。これは、Javaプログラミング言語の設計者の判断で、そのような例外を宣言する必要がプログラムの正確性の確立に大きく役立たないためです。Javaプログラミング言語の操作と構成の多くは、実行時に例外が発生する可能性があります。Javaコンパイラーが利用できる情報、およびコンパイラーが実行する分析のレベルは、プログラマーには明らかかもしれませんが、通常、そのような実行時例外が発生しないことを立証するには十分ではありません。このような例外クラスを宣言する必要があるのは、プログラマーにとっては苛立たしいことです。

たとえば、特定のコードは、構造上、null参照を含むことのない循環データ構造を実装する場合があります。プログラマーは、NullPointerExceptionが発生しないことを確信できますが、Javaコンパイラーがそれを証明することは困難です。データ構造のそのようなグローバルプロパティを確立するために必要な定理証明技術は、この仕様の範囲を超えています。

于 2012-07-11T18:02:40.213 に答える