例外隠蔽に使える?finally中return

概要

前のエントリーでScalaのreturnで遊んだ
http://d.hatena.ne.jp/kya-zinc/20090901
とき、Javaの挙動が気になったので、finallyについて調べてみた。
Scala同様、finally中でreturnまたはthrowすると、
tryの中のreturnやthrowを打ち消すことができると知った。

実験

  • returnreturn

try中のreturnはfinally中のreturnで上書きできる。

  • throwreturn

try中のthrowはfinally中のreturnで上書きできる。

  • returnthrow

try中のreturnはfinally中のthrowで上書きできる。

  • throwthrow

try中のreturnはfinally中のthrowで上書きできる。

public class JavaReturnTest {
  public static void main(String[] args){
    System.out.println(returnreturn());
    System.out.println(throwreturn());
    try {
      System.out.println(returnthrow());
    } catch (Throwable e) {
      e.printStackTrace();
    }
    System.out.println(throwthrow());
  }
  
  public static int returnreturn(){
    try {
      return 1;
    } finally {
      return 2;
    }
  }
  
  public static int throwreturn(){
    try {
      throw new Throwable();
    } finally {
      return 1;
    }
  }
  
  public static int returnthrow() throws Throwable{
    try{
      return 1;
    } finally {
      throw new Throwable();
    }
  }
  
  public static int throwthrow(){
    try {
      throw new Throwable();
    } finally {
      //no need for "throws" declaration
      throw new RuntimeException();
    }
  }
}

通常、catchしない(かつRuntimeExceptionでない)例外がthrowされるメソッドには
throws宣言が必要。
しかし、finallyでreturnする、またはRuntimeExceptionを投げればthrowsは不要らしい。
ただし以下のようなコンパイラ警告が出る。
"finally block does not complete normally"

さあ、returnで例外をなかったことにしよう!
例外が発生しなかった場合も同じreturnをすることになるけどね!