Java接口不会声明任何异常。如何管理已实施的已检查异常?

时间:2010-04-29 16:02:39

标签: java exception-handling interface

假设我有以下我可能修改的Java接口:

public interface MyInterface {
  public void doSomething();
}

现在实现它的类是这样的:

class MyImplementation implements MyInterface {
  public void doSomething() {
    try {
      // read file
    } catch (IOException e) {
      // what to do?
    }
  }
}

我无法从不读文件中恢复过来。

RuntimeException的子类可以明显地帮助我,但我不确定这是否是正确的做法:问题是该异常不会记录在类和类的用户中可能会得到这个例外,对解决这个问题一无所知。

我该怎么办?


我们都同意:界面有问题。

解决方案我选择了

我最后决定写一个MyVeryOwnInterface扩展MyInterface并添加MyRuntimeException

错误方法的签名的一部分
public interface MyVeryOwnInterface extends MyInterface {
  public void doSomething() throws MyRuntimeException;
}
class MyImplementation implements MyVeryOwnInterface {
  public void doSomething() throws MyRuntimeException {
    try {
      // read file
    } catch (IOException e) {
      throw new MyRuntimeException("Could not read the file", e);
    }
  }
}

6 个答案:

答案 0 :(得分:8)

您遇到了leaky abstractions的问题。没有非常好的解决方案,使用RuntimeException几乎是你唯一可以做的事情。

可以说,这也是为什么检查异常是失败概念的一个例子。

答案 1 :(得分:3)

我会抛出new IOError(e);并在界面的维护者处提出问题。

答案 2 :(得分:2)

如果你无法恢复而不需要抛出它,那么将它包装成RuntimeException或Error并抛出它。

public class Unchecked extends Error {

   private final Exception source;

   public Unchecked( Exception source) {
       this.source = source;
   }

   public String toString() {
       return "Unchecked Exception, Caused by: " + source;
   }

   public Exception getSource() {
       return source;
   }

   public static Unchecked wrap( Exception cause ) {
       return new Unchecked(cause);
   }
}

答案 3 :(得分:1)

显然,接口设计人员没有考虑doSomething()可能失败的可能性。理想情况下,他应该允许抛出IOException(如果他怀疑IO会被调用)或者可以用来封装IOException的SomethingException(checked)。

如果您可以使用界面设计人员,请与他们交谈并询问他们在发生故障时会发生什么。也许他们可以改变界面:或者根据接口的合同默认失败是可以接受的。

所有这些都失败了你可以选择默默地失败(可能是录音但没有响应问题)或抛出可能终止进程的RuntimeException。

答案 4 :(得分:0)

除了在界面中声明throws IOException之外,我认为没有任何事情要做。 这只是Java接口和已检查异常的本质。

您可以在类(doSomethingDangerous)中使用另一种方法抛出IOException。从doSomething - 实现中,您只需调用doSomethingDangerous(包含在try / catch中),然后您希望在doingSomething时直接调用doSomethingDangerous

答案 5 :(得分:0)

我建议

throw new RuntimeException("while reading file " + fileName + "...", e);

这不是问题,界面根本不会出现任何问题吗?

(您可能想要创建自己的OurCompanyDomainException扩展RuntimeException,以便在界面另一端的代码中轻松区分。)