直接上代码
class BaseException extends Exception{}
class DetailException1 extends BaseException{}
class DetailException2 extends BaseException{}
class MoreDetailException1 extends DetailException1{}
class BaseClass{
public BaseClass() throws DetailException1{}
public void method1() throws DetailException1{}
public void method2() throws DetailException1,DetailException2{}
}
class DetailClass1 extends BaseClass{
public DetailClass1() throws DetailException1,DetailException2{}
public void method1() {}
}
class DetailClass2 extends BaseClass{
public DetailClass2() throws DetailException1{}
public void method1() throws DetailException1{}
}
class DetailClass3 extends BaseClass{
public DetailClass3() throws DetailException1{}
public void method2() throws MoreDetailException1{}
}
我们来看看Java编程思想上说的几点:
- 当覆盖方法时,只能抛出其基类方法异常说明中列出的那些异常
- 异常限制对构造器不起作用,派生类构造器的异常说明必须包含其基类构造器的异常说明
- 派生类方法可以不跑出任何异常,即使是其基类方法所定义的异常
- 覆盖方法时,只能跑出基类异常或其子异常
从DetailClass1总可以看出,子类构造器可以多抛出其他异常,但一定要包含父类构造器抛出的异常。这个包含指的是一模一样,而不是子异常和父异常的概念。 比如: public DetailClass1() throws BaseException{} public DetailClass1() throws MoreDetailException1{} 都是不对的,编译通不过
相比于子类构造器可以多抛出其他异常,在覆盖方法时,子类却只能抛出父类方法的异常列表。如下 public void method1() throws DetailException1,DetailException2{} 是不允许的
从DetailClass3中的method2的覆盖可以看出,覆盖方法时,子类可以少抛父类的异常列表,且可以父类方法异常的子异常而不可以是父异常,如下: public void metod2() throws BaseException{} 是不允许的
以上可以总结为两点:
- 构造器异常列表必须包含父构造器异常列表。可多不少!
- 覆盖方法时,子类方法只能抛比父类方法异常更少,可以不抛异常,也可以抛子异常。可少不多!