为什么重写方法不能抛出比重写方法更广泛的异常?

我在阅读Kathe sierra的SCJP 6书时,遇到了关于在重写方法中抛出异常的解释。我完全不明白。谁能给我解释一下吗

重写方法不能抛出新的已检查异常
或比重写方法声明的范围更广。例如,一个
声明FileNotFoundException的方法不能被
方法,该方法声明SQLException、Exception或任何其他非运行时
异常,除非它是FileNotFoundException的子类

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

A类{
public void foo()引发IOException{..}
}
B类扩展了A类{
@凌驾
public void foo()抛出SocketException{..}//允许
@凌驾
public void foo()抛出SQLException{..}//不允许
}

SocketException扩展了IOException,但SQLException没有扩展

这是因为多态性:

A A=新B();
试一试{
a、 foo();
}捕获(IOEX异常){
//编译器强制捕获此信息
}

如果B决定抛出SQLException,那么编译器无法强制您捕获它,因为您正在通过其超类-A引用B的实例。另一方面,IOException的任何子类都将由处理IOException

您需要能够通过对象的超类引用对象的规则是Liskov替换原则

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

发表评论