我可以实现抛出最初抛出接口的异常子类型的方法吗?

时间:2014-06-11 02:00:47

标签: java exception polymorphism

我的计划有两个例外:

class AnException extends Exception {};
class SpecialException extends AnException{};

我有一个定义方法抛出AnException的接口:

interface TheInterface {
    public void method() throws AnException;
}

来自AnException的更多例外以及TheInterface的更多实现。这就是为什么我希望他们抛出原始异常并将它们转换为AnException

public class Implementation1 implements TheInterface {
    //Error: Overriden method does not throw AnException
    public void method() throws SpecialException {
    }
}

此时,似乎AnExpception衍生物浪费时间,因为它们从未被使用过,并且不会被铸造到他们的祖先身上。 但是,它们不会被method()直接抛出,而且它们有理由存在。看到我试过的这种解决方法:

@Override
public void method() throws AnExpception {
    try {
        return new OtherClassThatThrowsExceptions();
    }
    catch(SpecialException e) {
        //Netbeans says that I can't cast SpecialException to AnException
        throw (AnExpception)e;   
    }
}

1 个答案:

答案 0 :(得分:0)

其实我不确定你的问题是什么。如果您询问是否可以覆盖具有更多指定异常的方法,则回答

看一看。假设我们有您的例外情况并与您的基本方法接口

class AnException extends Exception {};
class SpecialException extends AnException {};

interface TheInterface {
    public void method() throws AnException;
}

现在让我们看一下编译器是否允许覆盖更多指定异常的方法

class Implementation1 implements TheInterface {

    @Override  
    public void method() throws SpecialException {
        throw new SpecialException();
    }

}

正如您所看到的那样编译得很好,因为这种方法没有问题。

假设您使用TheInterface类型的引用,它包含Implementation1的实例

TheInterface interface1 = new Implementation1();

如果您想使用此类参考编译器中的method,则需要您处理AnException,因为它无法确定对象interface1的确切类型这个方法的执行时刻。所以你需要写一些类似

的东西
try {
    interface1.method();
} catch (AnException e) {
    System.err.println("exception "+ e.getClass().getSimpleName()+ " handled");
}

并因为catch (AnException e)也会捕获实际抛出的SpecialException,因为它是AnException的子类型,保证会处理异常。

如果您将精确引用类型用于Implementation1

的实例
Implementation1 implementation1 = new Implementation1();

编译器将要求您处理SpecialException,因为此异常是在方法签名中指定的。因此,如果您想从此引用中调用method,则需要编写

try {
    implementation1.method();
} catch (SpecialException e) {
    System.err.println("exception "+ e.getClass().getSimpleName()+ " handled");
}

再次保证您的例外处理。