猜想一下,下面的代码会打印出什么呢?
public class Indecisive {
public static void main(String[] args) {
System.out.println(decision());
}
static boolean decision() {
try {
return true;
} finally {
return false;
}
}
}
这段代码看起来极不合理,decision方法既返回true又返回false,但编译的时候并没有发现问题。运行后发现打印出的是false。什么原因呢?
原因就是在一个try-finally语句中,finally语句块总是在控制权离开try语句块时执行。无论try语句块是正常结束的,还是意外结束的,情况都是如此。在一条语句或一个语句块抛出了 个异常,或者对某个封闭型语句执行break或continue语句,或是像这个程序一样在方法中执行了return语句时,将发生意外结束。之所以称为意外结束,是因为它们阻止程序按顺序执行下面的语句。
当try语句块和finally语句块都意外结束时,在try语句块中引发意外结束的原因将被丢弃,而整个try-finally语句意外结束的原因将取决于finally语句块意外结束的原因。在上面的程序中,在try语句块中return语句所引发的意外结束将被丢弃,而try-finally语句意外结束是由finally语句块中的return语句造成的。
关于更具体的try-catch-finally的执行结果可以参考JLS 14.20.2:http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20。
基于上面的事实,在设计finally代码时,要保证finally可以正常结束,对于任何在finally语句中可能招聘的受检查异常都要进行处理,而不是任其传播。