一尘不染

Java为什么覆盖方法不能引发比覆盖方法更广泛的异常?

java

我正在浏览Kathe sierra编写的SCJP 6,并遇到了有关以重写方法引发异常的解释。我真的不明白。有人可以向我解释吗?

覆盖方法不得抛出比被覆盖方法声明的异常新的或更广泛的检查异常。例如,声明FileNotFoundException的方法不能被声明SQLException,Exception或任何其他非运行时异常的方法覆盖,除非它是FileNotFoundException的子类。


阅读 606

收藏
2020-03-04

共1个答案

一尘不染

这意味着,如果某个方法声明抛出一个给定的异常,则子类中的重写方法只能声明抛出该异常或其子类。例如:

class A {
   public void foo() throws IOException {..}
}

class B extends A {
   @Override
   public void foo() throws SocketException {..} // allowed

   @Override
   public void foo() throws SQLException {..} // NOT allowed
}

SocketException extends IOException,但SQLException没有。

这是由于多态性:

A a = new B();
try {
    a.foo();
} catch (IOException ex) {
    // forced to catch this by the compiler
}

如果B决定抛出SQLException,则编译器无法强迫你捕获它,因为你是B通过其超类- 引用实例的A。另一方面,的任何子类IOException将由处理的子句(catchthrows)处理IOException

你需要能够按其超类引用对象的规则是Liskov替换原理。

由于未经检查的异常可以抛出到任何地方,因此它们不受此规则的约束。如果需要,可以将未经检查的异常作为文档形式添加到throws子句中,但是编译器不会对此执行任何强制措施。

2020-03-04