在我的程序中有两个例外:
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;
}
}
其实我不知道你的问题是什么。如果您正在询问是否可以用更指定的异常重写方法,那么答案是是。
看一下。假设我们有异常和与基方法的接口
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");
}
和你的异常保证被处理