java – 在重写方法中检查’throws’的exception
我正在实践exception处理机制,方法覆盖java …我的代码如下:
class base { void show() { System.out.println("in base class method"); } } class derived extends base { void show() throws IOException { System.out.println("in derived class method"); throw new IOException(); } } class my { public static void main(String[] args) { try { base b = new derived(); b.show(); } catch (IOException e) { System.out.println("exception occurred at :" + e); } } }
显示错误:
所以,我更正了以下内容:
void show() throws IOException{
它工作正常……
我做了另一个实验:
void show() throws Exception{
但它也显示错误:
据我所知,这是因为重写方法的throws
子句应该提到超类方法的throws
子句中的精确检查exception。
与第二种情况一样,如果我在throws子句中编写IOException
的超类Exception
,它也会显示错误。 为什么? 即使Exception
是所有exception的父类。
我只是试验过…这个错误告诉我不知道……
任何人都可以解释它说的内容以及在重写方法的throws
子句中提到已检查exception的限制是什么?
样本中有两个相关错误:
1)您的基类方法为派生类方法提供“模板”或基本标准 。
因此,基类应该声明一个超集,即派生类的相同exception类或基类exception类。 你不能声明它什么都不抛出,因为那时标准就不匹配了。
因此,如果派生类方法是这样的:
class Derived extends Base { void show() throws IOException { //... } }
然后基类方法“必须”是:
class Base { void show() throws /*Same or base classes of IOException*/ { //... } }
所以这两个工作:
class Base { void show() throws Exception { //... } }
要么
class Base { void show() throws Throwable { //... } }
2)当您尝试上述操作时, show
方法的整体声明现在变为throws Exception
。 因此,使用此show
任何人都必须捕获该exception。
在main
方法中,您将捕获IOException
。 这将不再有效,编译器抱怨“你好,你正在捕获IOException,那么Exception的所有其他可能性呢?” 这是您显示的第二个错误。
要解决此问题,请更改main
方法catch以包括在基类中声明的Exception
:
class My { public static void main(String[] args) { try { base b = new derived(); b.show(); } /* NOTE: CHANGED FROM IOException TO Exception */ catch (Exception e) { System.out.println("exception occurred at :" + e); } } }
重写方法在其throws
子句中可能只包含与超级方法相同的已检查exception,或者最多只包含派生类型。
例如,如果你说
class Base { public void foo(int y) throws IOException { // ... } }
和
class Derived extends Base { public void foo(int y) throws Exception { // ... } }
然后你的编译器会说Derived
中的foo
方法与其超类中的throws子句不兼容。
另一种方式是有效的,因为如果我说
class Base { public void foo(int y) throws Exception { // ... } }
和
class Derived extends Base { public void foo(int y) throws IOException { // ... } }
没关系。
为什么。
考虑一下方法的用法。 Java希望您以多态方式使用该方法,例如
Base a = new Derived(); a.foo(3);
因此,编译器将强制您捕获foo
在您声明的变量类型( Base
)中抛出的exception。 所以你的代码将成为
Base a = new Derived(); try { a.foo(3); } catch (Exception e) { // ... }
因此,您在Derived
类型中声明的Exception
的子类型对于上面的代码是可以的( Exception
的catch也适用于它的任何子类型)因此,Java将允许您在派生中声明IOException
,因为它以后不会再担心。