异常不与throws子句兼容的原因是什么?

时间:2012-05-09 09:31:39

标签: java exception exception-handling

任何人都可以告诉我异常可能有什么原因,而不是与"抛出"条款

例如:

class Sub extends Super{

    @Override
    void foo() throws Exception{

    }

}

class Super{

    void foo() throws IOException{

    }
}

异常异常与Super.foo()中的throws子句不兼容

4 个答案:

答案 0 :(得分:27)

如果没有完整的代码示例,我只能猜测:您正在重写/实现子类中的方法,但子类方法的异常规范与超类/接口的异常规范不兼容(即不是其子集)方法

如果声明基本方法根本不抛出任何异常,或者例如java.io.IOException(这是你的方法尝试抛出的java.lang.Exception的子类)。基类/接口的客户端期望其实例遵守base方法声明的契约,因此从该方法的实现中抛出Exception会破坏契约(和LSP)。

答案 1 :(得分:-1)

已检查的异常旨在用于方法可能期望其调用者准备好处理可能出现的某些问题的情况。如果BaseFoo.Bar()的呼叫者不需要处理FnordException,则方法DerivedFoo.Bar()也不能指望其呼叫者处理FnordException(因为它的许多呼叫者将是那些没有准备好BaseFoo.Bar()投掷它的人。)

从概念上讲,这很棒。在实践中,没有那么多。问题在于语言中检查的异常的设计假设没有呼叫者准备好优雅地处理特定问题,或者所有呼叫者都准备好处理它。在实践中,正常的事态是呼叫者没有准备好处理异常 - 即使是某些呼叫者可能能够处理的异常。大多数情况下,当代码收到一个未明确期望的已检查异常时,正确的操作过程是将其包装在未经检查的异常中并抛出它。具有讽刺意味的是,最简单的行动方案 - 增加一个“抛出”条款并让检查过的异常泡沫升起,可能是最不可能正确的。虽然有一些情况(例如IOException)这样的行为是有意义的(例如,当尝试从文件中读取集合时,读取一个项目时的I / O错误是读取时的I / O错误集合),从嵌套方法调用中抛出的异常将表示与外部方法抛出的相同类型的异常不同的条件,并且准备处理后者的代码可能不准备处理前者。

在您的情况下,您最好的选择可能是捕获IOException并将其包装在源自RuntimeException的其他类型中,并且知道您的呼叫者不太可能能够处理它。 / p>

答案 2 :(得分:-1)

要修复它,请使用 RuntimeException

public T findById(long id) throws RuntimeException {
    try {
          return whatEver.create();
    } catch (SystemException e) {
          throw new RuntimeException(e);
    }
}

希望这有帮助。

答案 3 :(得分:-1)

确保您在界面中声明了抛出。如果你这样做了,但问题仍然存在 - 尝试保存/重建项目。