2016-05-20 15 views
2

は、だから私はすべてのautocloseableインターフェースについて読み、リソースと試みるが、それは私が思ってしまうしました:私はAutoCloseableを実装するクラスをラップする(忘れた)していない場合はどうなりますAutoCloseableとガベージコレクションの関係

何そのクラスを使用するコード内のリソースで試してみてください。しかしそのクラスはOSからリソースを取っていますか? JVMがいつガベージコレクタを呼び出すべきかを決定する保証はありませんが、そうした場合、close()メソッドが呼び出されますか?

もしそうでなければ、これは私がC++のデストラクタを見逃す場所ですか? :) オブジェクトが解放されると(例えばスコープから外れて)、それが取ったすべてのOSリソースを解放するということは、そのクラスのコードではなく、ユーザーのコードではないことを確認する同様の方法はありますか?

答えて

1

このようなドキュメントを追加する必要はありません。ちょうどCloseableまたはAutocloseableと誰もが知っているようにしてください。ほとんどの場合、「close()を呼び出すことを忘れないでください」という簡単なコメントをインスタンスの取得に使用されるメソッド/コンストラクタに追加します。

もしそうでなければ、これは私がC++のデストラクタを欠場する場所ですか?

確かに、あなたはそれらを見逃してしまいます。 Javaには本当の意味での置き換えはありません。 finalize()と友人はむしろ使用できません。 GCが起動する前に、長い間、リソース(ファイル記述子など)がなくなっている可能性があります。

finalize()などを使用して警告を出力することができます。オブジェクトが以前に閉じられずにGC'edされた場合、それはリソースリークです。

非クローズドリソースにフラグを付ける静的解析ツールがあります。彼らはカスタムオブジェクトを扱う場合は考えませんが、(自動)closeableを実装するすべてのクラスを見ていると思います。

3

クラスによって異なります。 GCがオブジェクトを収集するときに呼び出されるfinalize()メソッドを実装するものと、close();を呼び出すものがありますが、保証されていません。

「yeehawと思うかもしれませんが、Javaにはデストラクタがあります!それは同じことではなく、あなた自身のクラスでfinalize()を実装することを勧められませんでした(私は16年間のJavaプログラミングのすべてを覚えていません)。

リソースを閉じることを忘れてしまったときにはすでに間違いを犯してしまっているので、代わりにそれを修正してください。 AutoCloseableではこれまでよりもずっと便利です。

+0

お返事ありがとうございますが、私の部分の主な混乱の点は変わっていません。私はユーザーコードに頼りたくはありません。ユーザーは、そのクラスを使用するコードです。そのため、どこかの人が明示的にclose()を呼び出すことや、try-with-resourcesを使用することを忘れると、災害は発生しません。 close()を使用してfinalize()を使用すると、ガベージコレクタの実装が行われたのでしょうか?繰り返しますが、OSリソースを使用するクラスのデザイナーとして、私は忘れてしまったユーザーでも問題ないように最善を尽くしたいと思っています。私は意味があることを願っています。 –

+0

私の(マイナー)編集を参照してください。 – Kayaman

+0

ここでは何も役に立ちません。あなたは 'finalize'を実装することができますが、APIを壊してしまったOSリソースと直接インターフェースをとっているのであれば、それは実現するでしょう。あなたが 'java.'パッケージからAPIを使用している場合、最後の手段としての' finalize'実装がほぼ確実に実現されます。あなた自身を書くことから得ることは何もありません。 – Tim