6

私が今まで知っていたのは、スーパークラスのメソッドをオーバーライドする場合、サブクラスは同じ例外または例外のサブクラスをスローする必要があるということです。

例えば:

正解です

class SuperClass {
    public int doIt(String str, Integer... data)throws ArrayIndexOutOfBoundsException{
 String signature = "(String, Integer[])";
 System.out.println(str + " " + signature);
 return 1;
 }
}

public final class SubClass extends SuperClass {
    public int doIt(String str, Integer... data) throws ArrayIndexOutOfBoundsException {
        String signature = "(String, Integer[])";
        System.out.println("Overridden: " + str + " " + signature);
        return 0;
    }

    public static void main(String... args) {
        SuperClass sb = new SubClass();
        try {
            sb.doIt("hello", 3);
        } catch (Exception e) {
        }
    }
}

これは正しくありません

class SuperClass {
    public int doIt(String str, Integer... data)throws ArrayIndexOutOfBoundsException{
 String signature = "(String, Integer[])";
 System.out.println(str + " " + signature);
 return 1;
 }
}

public final class SubClass extends SuperClass {
    public int doIt(String str, Integer... data) throws Exception {
        String signature = "(String, Integer[])";
        System.out.println("Overridden: " + str + " " + signature);
        return 0;
    }

    public static void main(String... args) {
        SuperClass sb = new SubClass();
        try {
            sb.doIt("hello", 3);
        } catch (Exception e) {
        }
    }
}

しかし、私の質問は、なぜこのコード ブロックがコンパイラによって正しいと見なされるのでしょうか?

class SuperClass {
    public int doIt(String str, Integer... data)throws ArrayIndexOutOfBoundsException{
 String signature = "(String, Integer[])";
 System.out.println(str + " " + signature);
 return 1;
 }
}

public final class SubClass extends SuperClass {
    public int doIt(String str, Integer... data) throws RuntimeException {
        String signature = "(String, Integer[])";
        System.out.println("Overridden: " + str + " " + signature);
        return 0;
    }

    public static void main(String... args) {
        SuperClass sb = new SubClass();
        try {
            sb.doIt("hello", 3);
        } catch (Exception e) {
        }
    }
}
4

4 に答える 4

6

これは、Java ではすべてのメソッドがRuntimeException(またはError) をいつでもスローできるためです。throwsメソッド署名の一部で宣言する必要さえありません。したがって、オーバーライドされたメソッドで宣言されたもののスーパータイプである例外をスローすることもできますが、それは依然として のサブタイプですRuntimeException

この動作の仕様、特に11.1.1については、Java 言語仕様の第 11 章 (例外) を参照してください。チェックされた(節で指定する必要がある)例外とチェックされていない(節で指定する必要がない)例外を定義する例外の種類throwsthrows

于 2012-09-30T18:16:08.230 に答える
2

メソッドをオーバーライドするときは、同じチェック例外を定義する必要があります。この場合、SuperClass#doItメソッドは をスローすることをArrayIndexOutOfBoundsException宣言するため、そのメソッドをオーバーライドするすべての子は、同じチェック済み例外またはそのサブクラスを宣言する必要があります。

より詳しい情報:

于 2012-09-30T18:12:02.630 に答える
1

簡単にするために、RuntimeExceptionErrorthrowsは句で宣言する必要はありませんが、常に暗黙的に宣言されます。暗黙の例外を宣言に含めると、スーパークラス メソッドの宣言を記述できます。

public int doIt(String str, Integer... data)
    throws ArrayIndexOutOfBoundsException, Error, RuntimeException {

つまり、サブクラス メソッドの明示的な RuntimeException 宣言は、スーパークラス メソッドの既存の (暗黙の) 例外のサブクラスであるため、許可されます。

于 2012-09-30T18:37:29.747 に答える
0

スーパー クラス メソッドが例外を宣言しない場合、サブクラスのオーバーライドされたメソッドは「チェック済み」例外を宣言できませんが、「チェックなし」例外は宣言できます。

于 2014-09-18T14:06:21.247 に答える