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); } } } 

显示错误:

cmd窗口

所以,我更正了以下内容:

 void show() throws IOException{ 

它工作正常……

我做了另一个实验:

 void show() throws Exception{ 

但它也显示错误:

cmd窗口

据我所知,这是因为重写方法的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 ,因为它以后不会再担心。