例外隠蔽に使える?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をすることになるけどね!