使用新检查的异常覆盖Java接口

时间:2012-08-06 20:41:46

标签: java exception exception-handling interface override

假设在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)。但是,显然异常不属于接口,但在实现类中也不能忽略。如果不是默默地失败,怎么能解决这个问题呢?

5 个答案:

答案 0 :(得分:13)

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

来自Java Language Specification, §8.4.8.3

  

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

答案 1 :(得分: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);
        }
    }
}

答案 2 :(得分:4)

界面是合同

enter image description here

所以你需要事先定义它。

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

答案 3 :(得分: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);
        }
    }
}

答案 4 :(得分: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的方式相同。