かとじゅんの技術日誌

技術の話をするところ

[Java] Java PUZZLERSを読み始めました&出題

Java Puzzlers 罠、落とし穴、コーナーケース

Java Puzzlers 罠、落とし穴、コーナーケース


この本を入手しました。今更ですが...。
Effective Java 第2版 (The Java Series)

Effective Java 第2版 (The Java Series)


Effective Javaで登場する多くの教訓がパズル形式で登場します。面白いですよ〜。
というわけで、この本からの問題。
このプログラムは何を表示するでしょうか?コンパイルできるかなども含めて考えてみてください。
答えは別のエントリにします。 やっぱり答えも下に書いちゃいます。

public class Indecisive {

  public static void main(String[] args) {
    System.out.println(decision());
  }

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

}

答えは、falseです。理由を理解するのは突然完了という動作を理解する必要があります。
try-finally文では、制御がtryブロックから抜けた時に、finallyブロックは常に実行される。ブロックが正常に処理される場合と、今回のようにreturnで突然に完了する(以下、突然完了という*1場合でも、finallyブロックは実行されます。
今回の場合だと、tryブロックとfinallyブロックの両方が突然完了している。この場合はtryブロックでの突然完了は破棄されてfinallyブロックで突然完了する。つまり、tryブロックでtrueを返そうとするが、キャンセルされてfinallyでfalseが返るということです。tryの突然完了の理由がかき消されてしまうわけです。
これを避けるには、finallyでreturnやbreak、continue, throwで抜けないようにしろ、とのこと。そして、finallyブロックでチェックされる例外もスローしちゃいけないそうだ。

自分ではfinallyではreturnするようなコードを書いたことがないが、常に意識したいことです。

追記:
decisionメソッドにstaticをつけ忘れた orz

*1:例外スローやbreakやcontinueが実行される場合でも突然完了する