首先,对不起我的英语不好。 题: 如果我有一个子类扩展了引发CHECKED Exception的方法,那么为什么Java允许我在子类的重写方法中抛出RuntimeException,如下例所示:
public class A {
public void doSomething() throws FileNotFoundException {
System.out.println("doing something...");
}
}
然后...
public class B extends A {
public void doSomething() throws RuntimeException { // <- my question
System.out.println("doing something here too...");
}
}
答案 0 :(得分:7)
任何方法都可以抛出RuntimeException
或Error
-未经检查的异常基类。因此throws RuntimeException
与其他任何内容都不相关。
您可以使用更窄的throws子句覆盖方法。 throws FileNotFoundException
并不意味着该方法必须抛出异常。基类中的方法可能会抛出它;在这种情况下,派生方法中的方法就不会。
您不能扩展throws子句,因为带有基类引用的客户端代码不会期望它。
这类似于协变返回类型,您可以在派生类/接口中缩小方法的返回类型。
答案 1 :(得分:3)
关于这些限制的整个想法是,子类不应强迫调用者捕获另一种类型的已检查异常,而不是被覆盖的方法声明指定的异常(无论是更广泛的定义还是完全不相关的声明)。 / p>
在您的情况下:
throws FileNotFoundException
中完全省略了B.doSomething
:这很好(如果子类的方法声明为抛出FileNotFoundException
的子类,那也很好)。如果B.doSomething()
声明为throws IOException
或诸如throws SqlException
之类的完全不相关的东西,将会出现问题。throws RuntimeException
声明它可以引发未经检查的异常。无论如何,调用者都不会被强制捕获未经检查的异常,因此这不会破坏任何编写来调用A.doSomething()