100

私の知る限り、次のコードスニペットはどちらも同じ目的を果たします。なぜfinallyブロックがあるのですか?

コードA:

try { /* Some code */ }
catch { /* Exception handling code */ }
finally { /* Cleanup code */ }

コードB:

try { /* Some code */ }
catch { /* Exception handling code */ }
// Cleanup code
4

11 に答える 11

149
  • 処理していない例外がスローされた場合はどうなりますか?(私はあなたが捕まえていないことを願っていますThrowable...)
  • tryブロックの内側から戻るとどうなりますか?
  • catchブロックが例外をスローした場合はどうなりますか?

finallyブロックは、どのようにそのブロックを終了しても(プロセス全体を明示的に中止するいくつかの方法を法として)、実行されることを確認します。これは、リソースの決定論的なクリーンアップにとって重要です。

于 2010-08-06T06:36:50.760 に答える
13

(少なくともJavaでは、おそらくC#でも)tryブロックを.なしでcatch、ただし。付きにすることも可能であることに注意してくださいfinally。ブロックで例外が発生すると、例外が上位にスローされる前にtry、ブロック内のコードが実行されます。finally

InputStream in = new FileInputStream("somefile.xyz");
try {
    somethingThatMightThrowAnException();
}
finally {
    // cleanup here
    in.close();
}
于 2010-08-06T06:57:29.720 に答える
7

tryまたはcatchブロックで何が起こっているかに関係なく、とにかく実行したいコードを配置することをお勧めします。

また、複数のcatchを使用していて、すべてのcatchブロックに共通のコードを配置する場合は、これを配置する場所になりますが、try内のコード全体が実行されたことを確認することはできません。

例えば:

conn c1 = new connection();
try {
    c1.dosomething();
} catch (ExceptionA exa) {
    handleexA();
    //c1.close();
} catch (ExceptionB exb) {
    handleexB();
    //c1.close();
} finally {
    c1.close();
}
于 2010-08-06T07:36:02.190 に答える
5

最後に、常に実行されますが、キャッチ後のコードは実行されない場合があります。

于 2010-08-06T06:36:37.457 に答える
2

アプリケーションが強制的に閉じられても、実行する必要のあるタスク(メモリの解放、データベースの閉じ、ロックの解放など)があります。これらのコード行をfinallyブロックに書き込むと、例外がスローされたかどうかに関係なく実行されます。いいえ...

アプリケーションはスレッドのコレクションである可能性があり、スレッドをException終了しますが、アプリケーション全体ではない場合finallyがあります。この場合、より便利です。

finallyJVMの失敗、スレッドの終了など、実行されない場合があります。

于 2012-09-12T10:11:29.550 に答える
1

スローされる可能性のある例外に関係なく、そのコードを実行する必要があるためです。たとえば、管理されていないリソースをクリーンアップする必要がある場合があります('using'構文はtry/ finallyブロックにコンパイルされます)。

于 2010-08-06T06:36:37.537 に答える
1

まだ下にスクロールしますか?どうぞ!

この質問は私にしばらく前に大変な時間を与えました。

try
{
 int a=1;
 int b=0;
 int c=a/b;
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}
finally
{
 console.writeline("Finally block");
}
console.writeline("After finally");

上記のシナリオでは何が印刷されますか?はい、それは正しいと思いました:

  • ex.Message--それが何であれ(おそらくゼロ除算を試みた)

  • 最後にブロックする

  • ついに

    try
    {
        int a=1;
        int b=0;
        int c=a/b;
    }
    catch(Exception ex)
    {
        throw(ex);
    }
    finally
    {
        console.writeline("Finally block");
    }
    console.writeline("After finally");
    

この印刷物は何でしょうか?何もない!catchブロックがエラーを発生させたため、エラーがスローされます。

優れたプログラミング構造では、このコードが別のレイヤーから処理されるという意味で、例外が集中します。このような場合を刺激するために、このコードをネストしてみます。

try
{    
 try
    {
     int a=1;
     int b=0;
     int c=a/b;
    }
    catch(Exception ex)
    {
     throw(ex);
    }
    finally
    {
     console.writeline("Finally block")
    }
    console.writeline("After finally");
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}

この場合、出力は次のようになります。

  • 最後にブロックする
  • ex.Message--それが何であれ。

例外をキャッチして他のレイヤーに再度スローすると(Funneling)、スロー後のコードが実行されないことは明らかです。これは、関数内の戻りが機能するのと同じように機能します。

これで、catchブロックの後にコードのリソースを閉じない理由がわかりました。finallyブロックに配置します。

于 2019-12-30T20:23:59.603 に答える
0

finallyJVMがシャットダウンされていない限り、常に実行されfinallyますが、クリーンアップコードを1か所に配置する方法を提供するだけです。

catch各ブロックにクリーンアップコードを配置する必要があるとしたら、面倒です。

于 2010-08-06T06:37:26.917 に答える
0

何があってもコードを実行したい場合があります。例外がスローされるかどうか。次に、を使用しfinallyます。

于 2010-08-06T06:41:25.010 に答える
0

catchブロックが例外をスローした場合、残りのコードは実行されないため、finallyブロックを作成する必要があります。

于 2016-06-09T11:15:21.490 に答える
0

最後に、Javaのブロックを使用して、ファイルのクローズ、接続のクローズなどの「クリーンアップ」コードを配置できます。


プログラムが終了した場合(System.exit()を呼び出すか、プロセスを中止させる致命的なエラーが発生した場合)、finallyブロックは実行されません。

于 2019-03-10T18:28:04.887 に答える