5

假设在 Java 中,我使用的是一个相当通用的预先存在的接口

public interface Generator {
    public String generate();
}

我有自己的课

public class FromFileGenerator implements Generator {
    ...
    public String generate() throws FileNotFoundException {
        String output = //read from some file
        return file;
    }
}

Java 编译器对我大喊大叫,因为 generate() 的实现包含原始签名中未指定的异常 (FileNotFoundException)。但是,显然异常不属于接口,但在实现类中也不容忽视。如果不只是默默地失败,如何解决这个问题?

4

5 回答 5

14

您不能将已检查异常添加到隐藏、覆盖或实现另一个方法的方法的声明中。您将需要在方法中捕获异常并对其执行其他操作(例如 returnnull或抛出未经检查的异常,可能包装已检查的异常)。

来自Java 语言规范,第 8.4.8.3 节

覆盖或隐藏另一个方法的方法,包括实现接口中定义的抽象方法的方法,可能不会被声明为抛出比被覆盖或隐藏的方法更多的检查异常。

于 2012-08-06T20:43:48.147 回答
5

接口是一个契约

在此处输入图像描述

所以你需要预先定义。

因此,您可以尝试一下,在方法体中捕获或修改合同。

于 2012-08-06T20:45:37.723 回答
4

不幸的是,没有办法很好地解决它:异常规范是接口的一部分,所以如果为你的Generator接口编程的人不希望看到FileNotFoundException,那么当他们使用FromFileGenerator.

解决它的一种常见方法是引入一个常见的异常,并将其包装FileNotFoundException起来:

public class GeneratorException extends Exception {
    public GeneratorException(Exception inner) {
        super(inner);
    }
}
public interface Generator {
    public String generate() throws GeneratorException;
}
public class FromFileGenerator implements Generator {
...
    public String generate() throws GeneratorException {
        try {
            String output = //read from some file
            return file;
        } catch (FileNotFoundException fnf) {
            throw new GeneratorException(fnf);
        }
    }
}
于 2012-08-06T20:44:35.193 回答
3

您可以将实现异常包装在未经检查的异常中并抛出:

public class FromFileGenerator implements Generator {
    ...
    public String generate() {
        try {
            String output = //read from some file
            return file;
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }
}
于 2012-08-06T20:45:37.140 回答
3

一个常见的解决方案是将异常包装在未经检查的异常中。所以你的班级可能看起来像:

public class FromFileGenerator implements Generator {
    ...
    public String generate() throws FileNotFoundException {
        try {
            String output = //read from some file
            return output
        } catch (FileNotFoundException e) {
            throw new IllegalStateException(e);
        }
    }
}

更好的是更改接口以拥有自己的已检查异常。然后,您可以将 FileNotFoundException 转换为已检查的异常,方法与转换为上面未检查的 IllegalStateException 的方式相同。

于 2012-08-06T20:48:33.747 回答