5

ほとんどの場合、finally ブロックが使用されているのは、次のようなものだけです。

FileInputStream f;
try{
    f= new FileInputStream("sample.txt");
    //something that uses f and sometimes throws an exception
}
catch(IOException ex){
    /* Handle it somehow */
}
finally{
    f.close();
}

私の質問は、f のスコープが囲んでいるブロックで終わっている場合、なぜそれを finally で閉じる必要があるのでしょうか?

4

5 に答える 5

20

ガベージ コレクションはリソースのクリーンアップと同じではないためです。

たとえば、範囲外になる JDBC 接続オブジェクトがある場合、開いているカーソルと接続が不要になったことを示すシグナルがデータベース サーバーに送信されません。これらのメッセージがないと、最終的に使用可能なカーソルと接続の数を使い果たしてしまいます。

ファイルハンドルやその他のリソースと同じです。自分で片付けなさい。

于 2011-10-04T17:59:19.730 に答える
6

あなたは悪い例を挙げました-あなたは次のようなことを意味していると思いますFileInputStream-しかし、基本的な理由は、Javaには決定論的なファイナライズがないためです。

変数のスコープは、変数 fが宣言されているブロック (tryブロックではない) で終了しますが、これは、オブジェクトへの「ライブ」参照が必ずしも存在しないという意味ではありません。それは決定論的な方法で。

リソースを任意の時間ぶら下げたままにしておく場合 (および、メモリが最終的に解放される前にファイナライザーが追加のコレクション ラウンドを必要とするため、ガベージ コレクションを遅らせる場合) を除き、明示的にリソースを閉じる必要があります。

基本的に、Java はC++ と同じように RAII をサポートしていません。C++ であるかのように使用しないでください。

于 2011-10-04T17:59:29.983 に答える
2

例外が発生した場合でも、finally は毎回呼び出されるためです。finally ブロックは、ファイル/接続が閉じられることを保証します。

于 2011-10-04T18:01:51.797 に答える
0

その理由は、オブジェクトへの特定の参照が範囲外になるとすぐにオブジェクトがガベージ コレクションされることを Java が保証しないためです。そのため、ファイル記述子などの限られたシステム リソースを参照するオブジェクトの場合、ガベージ コレクションを待つだけでは十分ではありません。

ただし、java.io.File実際にはそのようなオブジェクトではないことに注意してください。

于 2011-10-04T18:00:06.383 に答える
0

実行するたびに try catch finally ,finally ブロックすることで例外を処理しましたが、引数で渡された例外が一致した場合にのみ catch ブロックが実行されるため、catch の保証はありません。たとえば、データベース接続を開いている場合は、離れる前に閉じる必要があるため、finally に実装する必要があります。

于 2011-10-04T18:04:21.423 に答える