所以这是书中的引文:
重写方法不得抛出比重写方法声明的新异常或更广泛的已检查异常。例如,声明 FileNotFoundException 的方法不能被声明 SQLException、Exception 或任何其他非运行时异常的方法覆盖,除非它是 FileNotFoundException 的子类。
现在这是我的问题,如果超类中的方法抛出异常,那么覆盖方法根本就不会抛出异常吗?
因为我只是在Java中尝试过这个,覆盖方法没有抛出任何异常,并且没有错误。
请解释。
所以这是书中的引文:
重写方法不得抛出比重写方法声明的新异常或更广泛的已检查异常。例如,声明 FileNotFoundException 的方法不能被声明 SQLException、Exception 或任何其他非运行时异常的方法覆盖,除非它是 FileNotFoundException 的子类。
现在这是我的问题,如果超类中的方法抛出异常,那么覆盖方法根本就不会抛出异常吗?
因为我只是在Java中尝试过这个,覆盖方法没有抛出任何异常,并且没有错误。
请解释。
您可以将覆盖方法声明为抛出的异常类型比超类少,只是不能引入新的异常。子类方法必须与超类方法的行为兼容。更准确地说,您必须能够在不破坏任何内容的情况下将子类的对象替换为超类的对象(在 throws 子句中添加新的已检查异常意味着调用它的事物必须更改其代码来处理它)。
(这背后的想法是Liskov 替换原则:程序应该能够处理高级别的对象,而不会陷入关于所有事物的确切类型的详细信息。如果子类可以引入更改,则意味着程序必须将它们挑选出来并以不同的方式处理它们,那么它就违背了抽象的目的。)
因此,可以将覆盖方法声明为根本不抛出任何检查异常(通过完全省略 throws 子句),因为这不需要对任何调用者进行更改。
JDK 中有一些例子,比如 java.io,其中子类不可能抛出超类声明的异常(参见ByteArrayOutputStream关闭方法)。在这里,close 方法可以删除其 throws 子句,因为它从不抛出 IOException。(也许有人想用一个确实抛出 IOException 的版本对其进行子类化?)