[英]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);
}
}
}
显示错误:
所以,我更正了以下内容:
void show() throws IOException{
它工作正常......
我做了一个实验:
void show() throws Exception{
但它也显示错误:
据我了解,这是因为公司的覆盖方法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.