具有exception的覆盖方法

所以这是本书的引用:

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

现在这是我的问题,如果超类中的方法抛出exception,那么覆盖方法是否可以抛出exception呢?

因为我刚刚在Java中尝试了这一点,其中重写方法没有抛出任何exception,并且没有错误。

请解释。

您可以将重写方法声明为抛出比超类更少类型的exception,您只是不能引入新类型。 子类方法必须与超类方法的行为兼容。 更确切地说,您必须能够在不破坏任何内容的情况下将子类的对象替换为超类的对象(其中向throws子句添加新的已检查exception将意味着调用它的事情必须更改其代码以处理它)。

(这背后的想法是Liskov替换原则 :一个程序应该能够处理高级别的对象,而不会陷入关于所有确切类型的细节。如果子类可以引入更改,这意味着程序必须将它们挑出来以不同的方式处理它们然后它会破坏抽象的目的。)

因此,可以将重写方法声明为完全不抛出任何检查exception(通过完全省略throws子句),因为这不需要更改任何调用者。

JDK中有一些例子,例如在java.io中,子类不可能抛出超类声明的exception(参见ByteArrayOutputStream close方法)。 这里close方法可以删除它的throws子句,因为它永远不会抛出IOException。 (也许是因为有人想要用一个确实抛出IOException的版本对它进行子类化?)