質問
C++ では、コンストラクターでリソースを取得し、デストラクターで解放します。
そのため、関数の途中で例外が発生しても、リソース リークやロックされたミューテックスなどは発生しません。
私の知る限り、Javaクラスにはデストラクターがありません。では、Java でリソース管理を行うにはどうすればよいでしょうか。
例えば:
public int foo() {
Resource f = new Resource();
DoSomething(f);
f.Release();
}
DoSomething が例外をスローした場合、リソースを解放するにはどうすればよいでしょうか?コード全体に try\catch ブロックを配置することはできませんね。
解決
はい、コードの周囲に try/catch/finally ブロックを置くことができますし、そうすべきです。C# には省略表現の "using" ステートメントがありますが、Java では次のような問題が発生します。
public int foo() {
Resource f = new Resource();
try {
DoSomething(f);
}
finally {
f.Release();
}
}
他のヒント
この質問は 2008 年に遡ったものであるため、Java 6 に関するものです。それ以来、自動リソース管理の新機能を含む Java 7 がリリースされました。Java 7 に関連する最近の質問については、次の質問を参照してください。
Execute around イディオムを使用して、try/finally (および例外とアルゴリズム) を除外することができます。ただし、構文は非常に冗長です。
public int foo() {
withResource(new WithResource() { public void run(Resource resource) {
doSomething(resource);
}});
}
...
public interface WithResource {
void run(Resource resource);
}
public static void withResource(WithResource handler) {
Resource resource = new Resource();
try {
handler.run(resource);
} finally {
resource.release();
}
}
この種のことは、try/finally よりも抽象化している場合に意味があります。たとえば、JDBC を使用すると、ステートメントを実行し、結果をループし、リソースを閉じ、例外をラップできます。
using ブロックが必要な場合は、Java クロージャの議論に参加してください :S
がっかりさせて申し訳ありませんが、Java では する try\catch\finally ブロックを多用します。「たくさん」というのは、つまり、 たくさん. 。Java に C# using ブロックがあればいいのにと思うことがあります。ほとんどの場合、Java のガベージ コレクターがリソースを解放する必要はありません。
ただし、例外はエラー処理をよりクリーンにするために使用されます。独自の例外を作成し、何を行っていても例外をキャッチできます。ユーザーに任意のエラー コードを返す必要はもうありません。