考虑以下接口:
public interface Generator {
String generate() throws IOException;
}
以及以下实现:
public class EmptyStringGenerator implements Generator {
@Override
public String generate() {
return "";
}
}
请注意,我省略了接口throws IOException
中指定的签名部分。Generator
然而,没有编译器错误,没有编译器警告,甚至@Override
注释都没有抱怨。
我知道这是按预期工作的。但是,我想知道这背后的意图。如果我的方法实际上没有抛出一个IOException
,那么不抛出它就可以了,我不必将它从签名中删除。但是,如果我确实将它从我的方法签名中删除EmptyStringGenerator
,我将强制该类的所有当前和未来子类放弃抛出接口中实际指定的异常的可能性。
对我来说,这听起来像是一个并没有真正给你带来任何好处的功能(除了节省几次击键,这根本不是一个真正的好处),但在实际使用时有可能成为一个可怕的错误。
所以我的问题实际上是这样的:throws
在派生类中省略异常有什么意义?这种可能性解决了什么问题?为什么允许这样做?
更新
对于那些问“但那有什么害处?”的人,这是我的一个评论中的例子。顺便说一句,这并不牵强,因为这正是我现在正在处理的问题:
程序员 A 指定接口 I。程序员 B 编写实现类 X,但忘记添加 throws。他也从来没有注意到,因为这里甚至没有发出警告。程序员 C 写了实现类 Y,继承自类 X,他甚至特意也想把 throws 放在那里,因为他要扔了。但即使界面有规定,现在也不允许他再这样做了,因为B的疏忽。他实际上不再被允许在这里使用该例外。这是一个相当大的伤害。特别是如果 X 类不在您的控制之下。