16

当您需要抛出未在您正在实现的接口中定义的异常时,最佳实践是什么?

这是一个例子:

public interface Reader
{
    public abstract void read() throws IOException;
}

public class CarrotReader implements Reader
{
    public void read() throws IOException {}
}

public class CupcakeReader implements Reader
{
    public void read() throws IOException, CupcakeException {}
}

在这种情况下,您在读取纸杯蛋糕时会发生特定异常,因此您想抛出与此相关的异常。但是,Reader并没有在它的接口中定义这种类型的异常,那你怎么办呢?此外,将CupcakeException添加到Reader接口中的throws子句是没有意义的,因为这种类型的异常是CupcakeReader 特有的。解决此问题的一种方法是让Reader定义read以便它抛出一些父类型,例如Exception,但随后您会丢失异常的上下文。在这种情况下你应该怎么做?谢谢!


另一个有趣的情况涉及您无法控制的界面。在这种情况下,表明出现问题的最佳方式是什么?

出于说明目的,这里是另一个示例:

public interface Reader
{
    public abstract void read();
}

public class CupcakeReader implements Reader
{
    public void read() throws CupcakeException {}
}

在这种情况下,您无法更改Reader,但您想表明CupcakeReaderread方法出现问题。

4

6 回答 6

13

您可能必须改为创建预期类型的​​异常。

... catch(CupcakeException e) {
   throw new IOException("The sky is falling", e);
 }
于 2009-08-03T16:14:38.253 回答
9

使用称为 ReaderException 的东西作为异常层次结构的根接口。ReaderException 还将提供指向由于较低级别异常而引发的其他异常的链接。

于 2009-08-03T16:11:45.277 回答
2

异常是接口的一部分。如果您可以重新定义接口,请为接口中的所有异常定义一个通用父级。

您还可以使 CupcakeException 成为 IOException 的子项。

于 2009-08-04T01:13:36.307 回答
1

只是不要使用已检查的异常。

您展示的示例是检查异常不好的原因之一。

主要原因是您的纸杯蛋糕阅读器的用户必须处理您的异常,无论他是否对此感兴趣。

所以而不是:

Value value = reader.read();

你强迫他这样做:

Value value = null;
try {
    value = reader.read();
} catch (Exception e) {
    // now what??
}

value.doSomething();   // potential NPE here

想想哪个更好、更易读、更不容易出错,然后停止使用受检异常。

编辑:

我对负面评价感到惊讶。是否还有人认为受检异常很棒?如果是这样,这里有一些参考为什么你不应该使用检查的异常:

  • 没有现代框架使用检查异常(Spring、EJB3 等)
  • 此处包含代码示例的文章
  • StackOverflow主题
  • 有效的 Java(第 58 和 59 节)-这里
于 2009-08-03T17:02:07.630 回答
0

也许您可以创建一个抽象的 ReaderSpecificException 类,将它放在接口中,并从这个抽象类中继承 CupcakeException。

于 2009-08-03T16:11:44.747 回答
0

如果您创建一个更高的抽象异常作为 CupCakeException 的基类,则不会像将 CupCakeException 添加到 Reader 接口时那样将 Reader 接口绑定到特定实现。如果你不让一个 Exception 从另一个继承,那么异常类中有一个构造函数,它接受一个 throwable 作为第二个参数,就像 Thorbjørn Ravn Andersen 在他的简短代码示例中已经展示的那样。这使您能够生成更抽象的异常,并且代码的每个部分都需要了解更多信息,而不仅仅是“有错误”可以查找更高异常的原因。

于 2009-08-03T16:40:17.663 回答