到目前为止我所知道的是,如果重写超类方法,子类应该抛出相同的异常或异常的子类。
例如:
这是正确的
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) {
}
}
}
答案 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)
要尝试简化,RuntimeException和Error不需要在throws
子句中声明,但始终隐含。如果在声明中包含隐含的异常,则可以编写超类方法声明;
public int doIt(String str, Integer... data)
throws ArrayIndexOutOfBoundsException, Error, RuntimeException {
这意味着,子类方法上的显式RuntimeException声明是超类方法上现有(隐含)异常的子类,所以它是允许的。
答案 3 :(得分:0)
如果超类方法没有声明任何异常,则子类重写方法不能声明"检查"异常,但它可以声明"未选中"例外