我有一个类在重写方法中抛出更高的检查异常。我知道这是不允许的,但为什么这段代码有效?
package personaltestlevel1;
public class OverrideExcept {
public static void main(String args[]) {
S1 s = new S2();
try
{
s.show();
}catch (NullPointerException e){
System.out.printf(e.getMessage());
}
}
}
class S1{
public void show() throws NullPointerException {
try
{
System.out.println("not overriden");
}catch (Exception e){
throw new NullPointerException();
}
}
}
class S2 extends S1{
public void show() throws RuntimeException {
try
{
System.err.println("overriden");
}catch (Exception e){
throw new RuntimeException();}
}
}
我已经使用检查异常更新了我的示例 - 无论如何都可以。
答案 0 :(得分:1)
让我们以下面的代码为例(带有一些检查异常):
public class Parent {
public void m() throws Exception {
}
}
public class Child extends Parent {
public void m() throws FileNotFoundException {
}
}
public class Client {
public void test() {
Parent p = new Child();
try {
p.m();
} catch (Exception e) {
e.printStackTrace();
}
}
}
即使m
中的Parent
仅在throws子句中声明Exception
,Child
也可以声明FileNotFoundException
,因为FileNotFoundException
是一个Exception
。
如果您查看在Client
上调用m
的{{1}}可以抓住Parent
FileNotFoundException
引发的m
({1}}实际对象),只需声明Child
中的Exception
。
我认为这解释了为什么允许重写方法抛出一个不同的checked-exception或者被覆盖的方法中的一个子节点是没有意义的。
答案 1 :(得分:0)
你不能在重写方法中抛出更高或更广泛的异常,因为如果你使用超类引用(多态)引用派生类对象,那么编译器将只检查被重写方法的超类版本而不是实际派生类抛出的异常类型该方法的实现,在运行时解决。
在这里你可以抛出更广泛的异常,因为它是一个未经检查的异常(即编译器不打扰并检查未经检查的异常的类型)。
但是从方法中抛出RuntimeException是一种糟糕的编程习惯。