2011-10-04 8 views
5

Fの範囲は外側のブロックで終わる場合の時間のほとんどは、私が使用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(); 
} 

のようなもので、なぜ我々は最終的にそれを閉じる必要があります?

+0

あなたの場合、 'f'のスコープはtryブロックで終了しません。 –

+0

@Oli Charlesworth:これは明らかに読みやすい例です。 –

+0

ファイル参照を作成しても、後で参照できるように、例外がスローされる(またはファイルハンドルが作成される)わけではありません。 –

答えて

18

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

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

ファイルハンドルおよび他のリソースと同じです。あなた自身の後で掃除する。

+2

もちろん、もちろんです。しかし、なぜ「ついに」? –

+5

finallyブロックのコードは、例外がスローされた場合でも実行されることが保証されているためです。 – duffymo

+1

@Joe良い例。例外をスローするキャッチブロックがあれば、finallyブロックに何かを返すことはありません。その場合、例外はスローされません...私はこれを難しい方法を学ぶ;-) – Cygnusx1

6

あなたは悪い例を与えました - 私はあなたがFileInputStreamのようなものを意味していると思っていますが、基本的な理由はJavaに決定的な終了がないことです。 変数

範囲fは、それが(ないtryブロック)で宣言されていますブロックで終わるが、それは、オブジェクトへの「ライブ」参照もはや必ずしも存在しないという意味ではありません - とガベージコレクタは、オブジェクトをファイナライズしたり、決定論的な方法でガベージコレクションを行いません。

リソースが任意の長さの間滞っていて、メモリが最終的に解放される前にファイナライザが余分なラウンドを必要とするため、ガベージコレクションを遅延させたくない場合は、明示的にリソースを閉じる必要があります。

基本的にJavaはではありません。はC++と同じ方法でRAIIをサポートしています。あたかもC++であるかのように使用するべきではありません。

+0

あなたの提案を反映するように編集:私はちょうどメモリからCloseableを考えていたので、実際に適用する1つを与えてくれてありがとう:P –

0

Javaは、オブジェクトへの特定の参照が範囲外になるとすぐにオブジェクトがガベージコレクションされることを保証しません。したがって、ファイルディスクリプタなどの限られたシステムリソースを参照するオブジェクトの場合、ガベージコレクションを待つだけでは不十分です。

ただし、java.io.Fileは実際にそのようなオブジェクトではありません。

1

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

0

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

関連する問題