在子类中抛出异常的标准是什么

时间:2012-09-30 18:09:01

标签: java exception polymorphism method-overriding

到目前为止我所知道的是,如果重写超类方法,子类应该抛出相同的异常或异常的子类。

例如:

这是正确的

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 个答案:

答案 0 :(得分:5)

这是因为在Java中,每个方法都可以随时抛出RuntimeException(或Error)。它甚至不需要在方法签名的throws部分中声明。因此,只要它仍然是RuntimeException的子类型,就可以抛出一个异常,它是在重写方法中声明的异常类型。

有关此行为的规范,请参阅Chapter 11 (Exceptions) of the Java Language Specification,尤其是定义已检查11.1.1. The Kinds of Exceptions(需要在throws子句中指定)且未选中(不需要在throws子句中指定)例外。

答案 1 :(得分:2)

覆盖方法时,应定义相同的已检查异常。在这种情况下,SuperClass#doIt方法声明抛出ArrayIndexOutOfBoundsException,因此覆盖该方法的每个子节点都应声明相同的已检查异常或其子类。

更多信息:

答案 2 :(得分:1)

要尝试简化,RuntimeExceptionError不需要在throws子句中声明,但始终隐含。如果在声明中包含隐含的异常,则可以编写超类方法声明;

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

这意味着,子类方法上的显式RuntimeException声明是超类方法上现有(隐含)异常的子类,所以它是允许的。

答案 3 :(得分:0)

如果超类方法没有声明任何异常,则子类重写方法不能声明"检查"异常,但它可以声明"未选中"例外