2

ディスク フラット ファイル、DB、またはその他の形式の外部リソースなどの IO リソースを利用するクラスがある場合、実行されるオーバーライドされた finalize() メソッドでこれらのストリーム/接続を閉じることの長所と短所は何ですか? GC? これにより、既存の JVM GC を活用して、closeResources() などと呼ばれるクラス メソッドを呼び出すクライアントに依存したり、スパゲッティのような try-catch (ネストされた try-catch と ifs が私の最も嫌いなプログラミング構造)。

具体的な例として、単純なファイル読み取りラッパーがあります。クラスは で構築されString filePath、ファイルをList<String[]>. BufferedReaderファイルを開く際に問題が発生した場合 (catch 句)を閉じるなど、複数の場所で閉じる必要はありませんが、ファイルが正常に読み取られた場合なども閉じます。1 つの場所に配置して、オブジェクトがいつGCを取得しても、常に閉じていることを確認してください。

このアプローチは良い方法ですか、それとも Java の範囲内で高レベルの利便性を自分に与えようとしているのですか?

4

3 に答える 3

2

finalize()メソッドが呼び出されることが保証されていないため、これは良い考えではありません。

コードが完成したら、リソースを閉じる方が簡単で優れています。

ネストされたtry-finallyブロックを記述してリソースを正しく閉じるのが嫌いな場合は、commons-ioの IOUtilsのようなものを使用してリソースをサイレントに閉じます(または独自の単純なutilメソッドを記述してリソースをサイレントに閉じます)。

InputStream stream = ...;
try {
    ...
}
finally {
    IOUtils.closeQuietly(stream);
}
于 2012-10-18T15:45:22.507 に答える
2

IO リソースがインスタンス変数の場合は、メソッドで閉じる必要がありますfinalize()

なんで ?

  1. インスタンス変数であるため、一部のメソッドが繰り返し使用するため、開いた状態にする必要があります。

  2. finalize 以外のメソッドでそれを閉じると、 が作成されますtemporal coupling。つまり、クラスのユーザーは、特定の時間順序で特定のメソッドを呼び出す必要があることを知る必要があります。つまり、A を B の前に呼び出すなどです。

編集:

Java のドキュメントには、ガベージ コレクターが特定の時間に実行されることが保証されておらず、オブジェクトへの参照finalize()がある限り実行されないことが 記載されています。参照が残っている場合は、メモリ リーク、プログラミング エラーです。リソースがメソッドに対してローカルでない場合は、これが最適なオプションです。リソースがメソッドに対してローカルである場合は、 の最後で閉じます。finalize()finallytry/cath block

于 2012-10-18T16:01:42.500 に答える
0

はい、最終的にブロックすることは、接続、I/O ストリームなどのリソースを解放するための最良の方法です。

于 2012-10-18T15:54:19.977 に答える