类ExampleA继承Exception,类ExampleB继承ExampleA。
有如下代码片断:
try { throw new ExampleB("b") } catch(ExampleA e){ System.out.println("ExampleA"); } catch(Exception e){ System.out.println("Exception"); }
执行此段代码的输出是什么呢?
根据里氏代换原则[能使用父类型的地方一定能使用子类型],抓取ExampleA类型异常的catch块能够抓住try块中抛出的ExampleB类型的异常,所以输出:ExampleA。
那么下面代码的运行结果如何呢。(此题的出处是《Java编程思想》一书)
class Annoyance extends Exception {} class Sneeze extends Annoyance {} class Human { public static void main(String[] args) throws Exception { try { try { throw new Sneeze(); } catch ( Annoyance a ) { System.out.println("Caught Annoyance"); throw a; } } catch ( Sneeze s ) { System.out.println("Caught Sneeze"); return ; } finally { System.out.println("Hello World!"); } } }
答案是:
Caught Annoyance
Caught Sneeze
Hello World!
第一行和第三行没什么疑问,关键是第二行,应该出来吗?是不是子类捕获了父类的异常呢?
尽管
catch ( Annoyance a )
这一句使用的是父类的引用,但实际上是子类的对象,这是Java中多态的经典表现。在
catch ( Sneeze s )
的时候当然可以捕获到自己抛出来的异常了。