Puzzle 36: Indecisive

优柔寡断。

请看下面的代码片段:

static boolean decision() {
     try {
          return true;
     } finally {
          return false;
     }
}

具体代码在:https://cyiridiumsitewikineed.googlecode.com/svn/trunk/src/javapuzzlers/book/javapuzzlers/ch05/p36/Indecisive.java

上面这个方法的返回值是 true 还是 false 呢?按通常的判断:

1. 执行第一个 return 后,方法返回 ture,执行结束。

2. finally 的方法总是要执行,所以返回 false。

经过实验,返回值是 false。究其原因,是因为 Java 块运行规范所致:finally 块运行总是在控制权离开 try 块后运行,至于 try 块如何结束运行的,是否正常异常,是不考虑的。结束语句块有以下几种方式:

1. 正常结束

2. break / continue

3. return

4. 抛出异常

上面实验代码的结束方式就是第三种。同时,finally 块也是按第三种方式异常结束的。如果 try 和 finally 都是异常结束的话,那么返回值以 finally 为准。所以上面的方法最终返回 false。

但是如果是用 System.exit() 终止退出程序,又另当别论。如果在 catch 块中有这么句 System.exit(),程序执行到这里就 over 了,finally 块中也就没什么事了。这部分内容可以参考 Puzzle 39: Hello, Goodbye.

这个例子对于 Java 用户的教训是,不要在 try 块里使用 break / continue / return / throw,不要试图用它们来退出 finally 块。