-2

我有一个类在重写方法中抛出更高的检查异常。我知道这是不允许的,但为什么这段代码有效?

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();}


    }
}

我已经用检查的异常更新了我的样本 - 它无论如何都可以工作。

4

2 回答 2

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();
        }
    }
}

即使minParentException在 throws 子句中声明,Child也允许声明FileNotFoundException,因为FileNotFoundExceptionis-a Exception

如果您查看Clientwhich 调用monParent可以捕获in (实际对象)FileNotFoundException抛出的内容,只需在它中声明.mChildExceptioncatch

我认为这解释了为什么允许覆盖方法抛出一个不同的检查异常或方法中被覆盖的方法的子异常是没有意义的。

于 2013-03-21T19:09:23.323 回答
0

您不能在重写方法中抛出更高或更广泛的异常,因为如果您使用超类引用(多态性)引用派生类对象,那么编译器将只检查由重写方法的超类版本抛出的异常类型,而不是实际派生类实现方法,在运行时解决。

在这里您可以抛出更广泛的异常,因为它是未经检查的异常(即编译器不会打扰并检查未经检查的异常的类型)。

但是从方法中抛出 RuntimeException 是一种不好的编程习惯。

于 2013-03-21T19:02:37.490 回答