重写接口方法时删除 Java 检查的异常?

Removing Java checked exception while overriding interface method?

我正在使用 Java 7 并且发现了一些非常有趣的东西。在使用我自己的接口扩展 java.lang.Appendable 接口时,我明确地覆盖了每个方法,主要是出于文档目的。

java.lang.Appendable 中定义的所有三个方法都抛出 IOException,我认为我的覆盖方法也必须声明。但是,我最终删除了其中一个重写方法的 throws 子句,奇怪的是 Java 7 编译器没有抱怨缺少声明。所以我继续从其他两个方法中删除了 throws 子句,编译器没有抱怨。

那么为什么我可以覆盖接口中的方法并删除它的 throws 子句?这种现象什么时候在 Java 变得合法了?

父接口声明方法可能抛出异常。不抛出异常的实现符合 可能 的实现。您的接口声明实现实际上不会抛出异常,同时仍遵守父接口的约定。

将您的实例分配给 Appendable 变量的代码必须捕获所定义的异常,而将您的实例视为您的子接口的代码则不必如此。

简单地说:

interface Foo {
    void m() throws Exception;
}

interface Bar extends Foo {
    @Override
    void m();
}

void test(Foo foo, Bar bar) {
    foo.m(); // must catch exception
    bar.m(); // no exception declared to be thrown, so don't need to catch
}

另请注意,重要的是变量的类型,而不是对象:

Foo foo = new BarImpl();
foo.m(); // must catch exception