这意味着,如果某个方法声明抛出一个给定的异常,则子类中的重写方法只能声明抛出该异常或其子类。例如:
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将由处理的子句(
catch或
throws)处理
IOException
你需要能够按其超类引用对象的规则是Liskov替换原理。
由于未经检查的异常可以抛出到任何地方,因此它们不受此规则的约束。如果需要,可以将未经检查的异常作为文档形式添加到throws子句中,但是编译器不会对此执行任何强制措施。



