Java 调用引发选中异常的重写方法
阅读后,我了解到,如果声明为的方法引发选中的异常,则子类中的重写方法只能声明引发该异常或其子类:Java 调用引发选中异常的重写方法,java,exception-handling,overriding,Java,Exception Handling,Overriding,阅读后,我了解到,如果声明为的方法引发选中的异常,则子类中的重写方法只能声明引发该异常或其子类: class A { public void foo() throws IOException {..} } class B extends A { @Override public void foo() throws SocketException {..} // allowed @Override public void foo() throws SQLExcep
class A {
public void foo() throws IOException {..}
}
class B extends A {
@Override
public void foo() throws SocketException {..} // allowed
@Override
public void foo() throws SQLException {..} // NOT allowed
}
因此,因为SocketException
IS-AIOException
我可以将重写方法声明为抛出IOException
的任何子类
在我的程序中,我想调用声明为throwsFileNotFoundException
IS-AIOException
的重写方法。还使用try-catch块进行处理
import java.io.*;
class Sub extends Super{
public static void main (String [] args){
Super p = new Sub();
try {
p.doStuff();
}catch(FileNotFoundException e){
}
}
public void doStuff() throws FileNotFoundException{}
}
class Super{
public void doStuff() throws IOException{}
}
但我得到了编译时错误:
原因是什么?我有点困惑,因为基类的所有内容也都可用于子类
除了
IOException
(与覆盖概念相反)之外,捕获Exception
和Throwable
的功能也更令人困惑。这是因为您使用的是静态类型的Super对象。
编译器无法知道在运行时p指向子对象,因此它希望捕获由超类中声明的方法引发的异常您的对象引用类型为
Super
,即使您在运行时知道它是Sub
对象。因此,编译器正在检查Super
的方法定义,并给出此编译错误
这与获得以下编译器错误没有区别:
Object o = new String("Hello World");
o.charAt(2); //Obviously not allowed
请务必记住,throws
子句是方法定义的一部分
原因是什么?我有点困惑,因为基类的所有内容也都可用于子类
您需要捕获IOException
,而不是FilenotFoundException
。这是因为,虽然子类中的doStuff
方法将在运行时被调用,但编译器还不知道这一点。它只知道超类中的doStuff
方法,该方法声明它抛出一个IOException
要解决编辑问题:catch
块可以选择捕获try
块中预期的确切异常,也可以选择捕获异常的超类。这背后的原因与方法重写无关 因为它按声明的类型进行检查,在本例中是Super
不知道(或检查)您的p
仅包含Sub
的实例。而且,定义一个超类变量并仅对一个特定的子类使用它是没有意义的
因此,您的Super p
包含Super.class
的实例。它的方法<代码> doSuffes()/代码>可以抛出扩展的代码< >代码> IOExux,让我们说<代码> unSudioDeNoCudIdgule,但是您只尝试捕获<代码> FieloToFunDestExpOp> <代码>,以便<代码>未支持…< />代码>可能已经被抛出并必须处理。< / P> < P>编译器不考虑对象的类型,但是您使用的引用类型是Super
由于Super.doStuff()抛出IOException
,这是您必须捕获的
顺便说一句,我强烈建议您使用IDE,您会发现它更高效。将p声明为超级
Super p = ...
您的编译器只知道p
是某种Super
Super
的doStuff()
抛出一个IOException
,但您的代码只捕获IOException
的一个特例,即FileNotFoundException
。如果你想告诉你的编译器这确实是一个Sub
而不是一个Super
,只需将p
声明为Sub
在这种情况下,它不是显式地声明为Sub
,而是声明为Super
,因此任何Super
或其子对象都可能出现,并抛出任何IOException
,这可能不是FileNotFoundException
或其子对象。有些人可能会阻止图像。您还可以复制粘贴问题中的编译错误吗。@CKK现在添加了只需更改Super p=new Sub()代码>至Sub p=new Sub()
但是,java.lang.Object没有charAt
方法,而Super
和Sub
都同意。然而,原理是完全相同的,编译器只检查您调用的方法是否在引用类型上(Object
在我的示例中,在您的示例中,Super
)。除了IOException
之外,我怎么还可以使用Exception
和Throwable
?这与只能声明抛出该异常或其异常的重写相反subclass@Pau重写的方法无法抛出这些,但您可以捕获它们
Super p = ...