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

为了尽量简化,RuntimeExceptionError不需要在throws子句中声明,但总是隐含的。如果在声明中包含隐含的异常,则可以编写超类方法声明;

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 回答