工作有些年头,抽空回来看了下java基础,发现还是有遗忘或者被忽略的知识点,比如下面要说的:继承时对异常的处理
父类中未抛出异常
public class Parent {
//父类中的测试方法,打印相应语句以便测试
public void test() {
System.out.println("parent test");
}
}
ok, 没毛病,父类很简单,下面我们搞一个子类过来,继承一下这个父类,并抛出一个异常。
public class Child extends Parent {
public void test() throws Exception {
System.out.println("child test");
}
public static void main(String[] args) {
Parent test = new Child();
test.test();
}
}
不好意思,编译不通过。IDE告诉我们“overridden method does not throw 'java.lang.Exception'”,好尴尬不是么!不过还好,我们吸取了教训,知道了父类未抛出异常时,子类也不能抛出异常
的约定,至少没在项目发布上线后才发现问题,万幸万幸。
父类中抛出异常
public class Parent {
//和上面类似,只是抛出了一个异常
public void test() throws Exception {
System.out.println("parent test");
}
}
同样的,再搞一个子类出来,或者也可以将上面的子类稍作修改。如下:
public class Child extends Parent {
public void test() {
System.out.println("child test");
}
public static void main(String[] args) {
Parent test = new Child();
test.test();
}
}
编译...,what?又报错了。IDE告诉我们,main函数中test.test()
这一行有问题,必须要抛出一个异常。好吧,忍了,try..catch一下,再次编译运行,屏幕打印出child test
字样,心好累,终于成功了一次。
那...如果我按正常的来,Child中的test也抛出异常呢,像下面这样:
public void test() throws Exception {
System.out.println("child test");
}
嗯,和预想的一样,没问题。
如果...我子类不是抛出Exception,而是其子类比如IOException呢?
public void test() throws IOException {
System.out.println("child test");
}
嗯嗯,不错,依然没毛病,运行结果和前面一样。
那我把子类和父类的异常掉个包应该也没问题吧:
public class Parent {
//父类抛出IOException
public void test() throws IOException {
System.out.println("parent test");
}
}
public class Child extends Parent {
public void test() throws Exception {
System.out.println("child test");
}
public static void main(String[] args) {
Parent test = new Child();
try {
test.test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
哎呀,竟然又报错了。看来街坊邻居们传的没错,继承体系就是这么“小气”,子类的异常类型必须和父类相同或者是其子类
先折腾到这里吧,做个小结:
- 父类中相应方法未抛出异常时,子类也不能抛出异常(后经测试,子类抛出RuntimeException或其子类是可以的)
- 父类中抛出异常时,子类可以不抛出异常,但引用句柄是父类类型时,必须对异常进行处理(父类抛出RuntimeException可不用做处理)。
- 父类中抛出异常时,子类如果抛出异常,则必须为父类中异常的子类或和其一样。