简体   繁体   English

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

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

I was practicing exception handling mechanisms with method overriding in java...My code is as follows: 我正在使用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);
        }   
    }
}

Showing an error : 显示错误:

cmd窗口

So, I corrected following: 所以,我更正了以下内容:

void show() throws IOException{

and it is working correctly... 它工作正常......

One more experiment I did : 我做了一个实验:

void show() throws Exception{

but it was also showing an error: 但它也显示错误:

cmd窗口

As I understand, this is because of an overridden method's throws clause should mention the exact checked exception in throws clause of super class method. 据我了解,这是因为公司的覆盖方法throws条款应提及确切的检查异常的throws父类方法的条款。

As in second case, if I write IOException 's superclass Exception in throws clause, it also shows an error. 与第二种情况一样,如果我在throws子句中编写IOException的超类Exception ,它也会显示错误。 why? 为什么? Even if Exception is parent class of all exceptions. 即使Exception是所有异常的父类。

I just experimented...what this error tells I don't know... 我刚试验过...这个错误告诉我不知道......

Can any one please explain what it says and what are the constraints for mentioning checked exception in throws clause of an overridden method? 任何人都可以解释它说的内容以及在重写方法的throws子句中提到已检查异常的限制是什么?

There are two related errors in the sample: 样本中有两个相关错误:

1) Your base class method provides the "template" or basic criteria for the derived class method. 1)您的基类方法为派生类方法提供“模板”基本标准

So, the base class should declare a super-set ie either the same exception class or base exception class of the derived class. 因此,基类应该声明一个超集,即派生类的相同异常类或基类异常类。 You cannot declare that it throws nothing, because then the criteria will not match. 您无法声明它不会抛出任何内容,因为那时条件将不匹配。

So if your derived class method is like this: 所以如果你的派生类方法是这样的:

class Derived extends Base {
    void show() throws IOException {
        //...
    }
}

Then base class method "must" be: 然后基类方法“必须”是:

class Base {
    void show() throws /*Same or base classes of IOException*/ {
        //...
    }
}

So both of these work: 所以这两个工作:

class Base {
    void show() throws Exception {
        //...
    }
}

or 要么

class Base {
    void show() throws Throwable {
        //...
    }
}

2) When you try the above, the overall declaration of your show method now becomes throws Exception . 2)当您尝试上述操作时, show方法的整体声明现在变为throws Exception As a result, anyone who uses this show must catch that exception. 因此,使用此show任何人都必须捕获该异常。

In your main method, you are catching IOException . main方法中,您正在捕获IOException This will no longer work, the compiler complains "ok you are catching the IOException, what about all the other possibilities from Exception?" 这将不再有效,编译器抱怨“你好,你正在捕获IOException,那么Exception的所有其他可能性呢?” This is the second error that you showed. 这是您显示的第二个错误。

To fix this, change the main method catch to include Exception as declared in the base class: 要解决此问题,请更改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);
        }   
    }
}

Overridden methods may contain only the same checked exceptions in their throws clause as the super-method, or derived types at most. 重写方法在其throws子句中可能只包含与超级方法相同的已检查异常,或者最多只包含派生类型。

For example if you say 例如,如果你说

class Base {

    public void foo(int y) throws IOException {
        // ...
    }
}

and

class Derived extends Base {

    public void foo(int y) throws Exception {
        // ...
    }
}

then your compiler will say that the foo method inside Derived is incompatible with the throws clause in its superclass. 然后你的编译器会说Derived中的foo方法与其超类中的throws子句不兼容。

The other way around works because if I say 另一种方式是有效的,因为如果我说

class Base {

    public void foo(int y) throws Exception {
        // ...
    }
}

and

class Derived extends Base {

    public void foo(int y) throws IOException {
        // ...
    }
}

it's OK. 没关系。

Why. 为什么。

Think about the usage of your methods. 考虑一下方法的用法。 Java expects you to be using the method polymorphically such as Java希望您以多态方式使用该方法,例如

Base a = new Derived();
a.foo(3);

As such, the compiler will force you to catch the exception thrown by foo in your declared type of the variable ( Base ). 因此,编译器将强制您捕获foo在您声明的变量类型( Base )中抛出的异常。 So your code will become 所以你的代码将成为

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

Therefore, the subtype of Exception you declared in the Derived type is OK with your code above (a catch for an Exception will work for any of its subtypes as well) and as such, Java will allow you to declare IOException in derived, because it will cause no worries later on. 因此,您在Derived类型中声明的Exception类型可以使用上面的代码( Exception的catch也适用于它的任何子类型)因此,Java将允许您在派生中声明IOException ,因为它以后不会再担心。

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

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