- PR -

finallyブロックは正常に完了しません。の警告

投稿者投稿内容
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-10-31 01:52
コード:
try{
    hoge();
}catch(Exception e){
    e.printStackTrace();
}finally{
    return;
}


で、hoge()によってExceptionがスローされればcatch節が実行されますが、
Throwableがスローされた場合はcatch節が無視されてreturnされますね。
さらにcatch節自体書かなくても動きました。

トリビアだけど、これはやっちゃ駄目ですね。。。(同じく)
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2006-10-31 11:06
Throwableはチェック例外でないので、catch節がいらない。
ThrowableはExceptionでないので、catchされない。
※IOExceptionをcatchするようにしてもExceptionはcatchしないですよね?

常識だと思ってた。マジで。

おっと、Throwableはチェック例外だったのね・・・(失礼)
って、使わないだろーー(イイワケ)

[ メッセージ編集済み 編集者: tak3 編集日時 2006-10-31 11:12 ]
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-10-31 11:47
Throwable
├Error (非チェック)
└Exception
 └RuntimeException (非チェック)

となっているので、catch(Exception)ではThrowableはcatchされませんね。
通常だとコンパイル時にエラーとなりますが…


finallyはそんなに難しいものではなくて、
とにかくtry節を通常に抜けたり、returnで抜けたり、例外がthrowされたり、
どんな形であっても抜けるときに実行されます。

コード:
try {
    // (1)
} catch (HogeException e) {
    // (2)
} finally {
    // (3)
}
// (4)



まず、(1)を処理しますね。

■(1)を正常に通過した場合
  → (3) を処理して (4)に流れます
■(1)でreturnした場合
  → (3) を処理してreturnします
■(1)でキャッチされない例外が発生した場合
  → (3) を処理して例外がthrowされます
■(1)でHogeExceptionが発生した場合
  → (2) を処理して(3)を処理、(4)に流れます
■(1)でHogeException時、(2)のcatch節でreturnした場合
  → (3) を処理してreturnします
■(1)でHogeException時、(2)のcatch節で例外が発生した場合
  → (3) を処理して例外がthrowされます

と、どんなことがあろうが(3)が実行されます。

気をつけないといけないのが本スレッドの話題のケースですね。
(3)でreturnを行うと、try節でのreturnや、throwをキャンセルしてreturnします。
(3)でthrowした場合も同様です。

コード:
try {
    return 1; // (1)
} catch (HogeException e) {
    return 2; // (2)
} finally {
    return 3; // (3)
}


このケースでは、(1)でreturnした後に(3)が実行され、
メソッドの戻り値は3になります。
(1)直前でHogeExceptionが発生した場合、(2)でreturnした後に
(3)が実行されメソッドの戻り値は3となります。

このように、finally節でreturnを行うとtry節やcatch節での
returnした値が一切合財無効になるのでやってはいけないということです。
finally節で例外をthrowした場合も同様です。
すひろ
大ベテラン
会議室デビュー日: 2006/10/17
投稿数: 124
お住まい・勤務地: 愛知県
投稿日時: 2006-10-31 20:58
みなさん、返信ありがとうございます。
おかげさまでtry-catch-finallyに対する勘違いに気付く事ができました。

スキルアップ/キャリアアップ(JOB@IT)