繁体   English   中英

java - 在重写方法中检查'throws'的异常

[英]java - checked exception for 'throws' in overridden method

我正在使用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父类方法的条款。

与第二种情况一样,如果我在throws子句中编写IOException的超类Exception ,它也会显示错误。 为什么? 即使Exception是所有异常的父类。

我刚试验过...这个错误告诉我不知道......

任何人都可以解释它说的内容以及在重写方法的throws子句中提到已检查异常的限制是什么?

样本中有两个相关错误:

1)您的基类方法为派生类方法提供“模板”基本标准

因此,基类应该声明一个超集,即派生类的相同异常类或基类异常类。 您无法声明它不会抛出任何内容,因为那时条件将不匹配。

所以如果你的派生类方法是这样的:

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任何人都必须捕获该异常。

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子句中可能只包含与超级方法相同的已检查异常,或者最多只包含派生类型。

例如,如果你说

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 )中抛出的异常。 所以你的代码将成为

Base a = new Derived();
try {
    a.foo(3);
} catch (Exception e) {
    // ...
}

因此,您在Derived类型中声明的Exception类型可以使用上面的代码( Exception的catch也适用于它的任何子类型)因此,Java将允许您在派生中声明IOException ,因为它以后不会再担心。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM