【问题标题】:Removing Java checked exception while overriding interface method? [duplicate]在覆盖接口方法时删除 Java 检查异常? [复制]
【发布时间】:2016-08-29 23:36:26
【问题描述】:

我正在使用 Java 7,遇到了一些非常有趣的事情。在使用我自己的接口扩展 java.lang.Appendable 接口时,我明确地重写了每个方法以用于文档目的。

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

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

【问题讨论】:

  • 为什么不合法?为什么你必须错误地声明你的方法会抛出一个你知道它不会抛出的异常?
  • 我在想如果有人说 Appendable a = new MyInterfaceImpl();当他们说 a.append("Foo");他们的代码仍然必须尝试捕获 IOException(他们会这样做)。但我想如果 MyInterface 不为 Appendable 方法抛出 IOException 是有道理的,那没关系,因为 MyInterface 实现永远不会抛出 IOException。我只是惊讶地看到这项工作就是这样。感谢您的洞察力!

标签: java exception interface overriding


【解决方案1】:

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

将实例分配给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

【讨论】:

  • 太棒了,这很有意义。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 2015-08-20
  • 2021-08-12
相关资源
最近更新 更多