新しい例外をスローしても、finallyブロックは実行されますか?


142

このコードではsomeVar、catchブロックが実行され、2番目の例外がスローされた場合でも設定されますか?

public void someFunction() throws Exception {
    try {
        //CODE HERE
    } catch (Exception e) {
        Log.e(TAG, "", e);
        throw new Exception(e);
    } finally {
        this.someVar= true;
    }
}

2
@GaryFで示されているように、動作が予想と異なる状況があるため
jax

1
最後のブロックが例外をスローしたりリターンしたりすると、期待どおりに実行されない可能性があることに注意してください。
Peter Lawrey、2010年

回答:


184

はい、最終的にブロックは常に実行されます...次の場合を除きます:

  • try-catch-finallyブロックを実行しているスレッドが強制終了または中断された
  • あなたが使う System.exit(0);
  • 基になるVMが他の方法で破棄された
  • 基盤となるハードウェアが何らかの理由で使用できない

さらに、finallyブロックのメソッドがキャッチされない例外をスローした場合、その後は何も実行されません(つまり、他のコードと同じように例外がスローされます)。これが発生する非常に一般的なケースはjava.sql.Connection.close()です。

余談ですが、私が使用したコードサンプルは単なる例であると思いますが、finallyブロック内に実際のロジックを配置しないように注意してください。finallyブロックは、実行が必要なロジックではなく、リソースのクリーンアップ(DB接続のクローズ、ファイルハンドルの解放など)を目的としています。実行する必要がある場合は、try-catchブロックの前に実行し、例外をスローする可能性のあるものから離れてください。意図はほぼ確実に機能的に同じであるためです。


4
「try-catch-finallyブロックを実行しているスレッドが[...]中断される」とはどういう意味ですか?おそらくそのドキュメントの言葉遣いは不適切ですが、Thread.interrupt()は、tryまたはcatchブロックからスローされたかどうかにかかわらず、finallyブロックをスキップしません。これは「中断された」を使用して、Thread.stop()などのより暴力的なものを意味しますか?
Joe Kearney

@Joe:はい、私はこのドキュメンテーションはここで少し不適切に書かれていると思います、そしてそれらはスレッドのアクティビティへの一般的な中断を意味します。
GaryF 2010年

@GaryF-私はあなたがJLSから引用していると思います。JLSの言い回しは少し奇妙な場合がありますが、通常、奇妙な用語の意味はドキュメントの他の場所で明確に定義されています。JLSは仕様であり、主な目標として(読みやすさではなく)精度があります。
スティーブンC

1
@Stephen C-実際、これはJavaSEチュートリアル(他の人がリンクしている)からのものです。JLSでも同じように表現されているかもしれませんが、関連する部分が見つかりません。第11章(例外)、第14章(ステートメント)、または第15章(式)ではこれを期待していましたが、割り込みを明示的に参照するものは何もありません。私は確かにそれを見ることに興味があります。
GaryF 2010年

1
@GaryF-なるほど。実際、JLSはステートメントの「通常の」および「突然の」終了について話し、用語を定義するセクション(14.1)があります。の動作はfinally、通常の終了と突然の終了に関して指定されます。
スティーブンC

10

はい。

ドキュメントを参照してください:

finallyブロックは、tryブロックが終了すると常に実行されます。

例外:

注:tryまたはcatchコードの実行中にJVMが終了した場合、finallyブロックは実行されない可能性があります。同様に、tryまたはcatchコードを実行しているスレッドが中断または終了すると、アプリケーション全体が継続していても、finallyブロックが実行されない場合があります。


2

最後に、ブロックは常に実行されます。

public class ExceptionTest {

public static void someFunction(String input) throws Exception {
    try {
        if( input.equals("ABC") ) {
            System.out.println("Matched");
        }
    } catch (Exception e) {
        throw new Exception(e);
    } finally {
        System.out.println("Input Is "+input+" Finally Executed!!!");
    }
}

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
        System.out.println("********* Test with VALUE ********* ");
        someFunction("ABC");
        System.out.println("\r\n********* Test with NULL  ********* ");
        someFunction(null);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Javaトライキャッチが最終的にスローでブロック


2

最後に、あなたのケースが何であれ、常に実行されます

  • try-catch-finallyブロック
  • 投げる

チェックされていない例外の場合、Javaはエラー処理を強制しません。これが理由です。finallyブロックで未チェックの例外が発生し、その処理が行われない場合、このポイント(エラーが発生した場所)の下に記述されたコードは実行されません。

したがって、チェックされているかどうかにかかわらず、常にすべての例外を処理することをお勧めします。これにより、チェックされていない例外が発生した場合でも、finallyのコードブロックも確実に実行されます。サブネストキャッチの場所があり、最後にブロックして必要な作業を完了します。



1

はい。finallyブロックは、Java VMを停止するためにSystem.exit()を呼び出す場合を除いて、常に実行されます。


System.exit()の後でシャットダウンフックが呼び出されますが、既存の非システムスレッドはすべて停止されます。
Peter Lawrey、2010年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.