私は複数のCloseable
リソースを管理するJavaクラスを作成しようとしています。 C++ソリューションは、リソースの数が多い、簡単かつ容易に拡張することになります。Javaで閉じるオブジェクトを作成するには?
class composed_resource
{
resource_a a;
resource_b b;
resource_c c;
composed_resource(int x)
: a(x), b(x), c(x)
{ }
~composed_resource()
{ }
};
私の素朴なJavaソリューション:
public class ComposedResource implements Closeable
{
private final ResourceA a;
private final ResourceB b;
private final ResourceC c;
public ComposedResource(int x) /* throws ... */ {
a = new ResourceA(x);
try {
b = new ResourceB(x);
try {
c = new ResourceC(x);
} catch (Throwable t) {
b.close();
throw t;
}
} catch (Throwable t) {
a.close();
throw t;
}
}
@Override
public void close() throws IOException {
try {
a.close();
} finally {
try {
b.close();
} finally {
c.close();
}
}
}
}
A若干改善バージョン:
public class ComposedResource2 implements Closeable
{
private final ResourceA a;
private final ResourceB b;
private final ResourceC c;
public ComposedResource2(int x) /* throws ... */ {
try {
a = new ResourceA(x);
b = new ResourceB(x);
c = new ResourceC(x);
} catch (Throwable t) {
close();
throw t;
}
}
@Override
public void close() throws IOException {
try {
if (a != null) a.close();
} finally {
try {
if (b != null) b.close();
} finally {
if (c != null) c.close();
}
}
}
}
があります例外安全性を維持しながら、ネストされたtry-catchブロックを回避するより洗練されたソリューションそれは3つのリソースで管理可能ですが、それ以上のものは扱いにくくなっています。 (それはローカルスコープだった場合、私はちょうど「してみてください-と資源」ステートメントを使用することができますが、それはここでは適用されませんです。)
をjava.rmi
で作業しながら、私はこれについて考えました。コンストラクタでは、レジストリの作成/参照、オブジェクトの検索、オブジェクトのエクスポートを行っています。 close()は、オブジェクトの登録を解除し、オブジェクトをアンエクスポートする必要があります。私はラッパーオブジェクトを作成してexport/unexportを処理することを考えました(RAIIを利用するためにC++でやったように)が、私はそれほど助けにならないことに気付きました(私はJavaの専門家ではない、私は大学で使う必要があります)。
現時点では、私は上記のComposedResource2
のようなものを使用しており、正常に動作します。しかし今、より洗練されたソリューションがあるかどうかを知りたいと思っています。
ユースケースを提示できますか?たぶん具体的な例を使って作業すると、抽象的な問題よりも優れた答えが得られるでしょう... –
リソースは試用できません。 –
1)コンストラクタでリソースを作成しないでください - 理想的には、フィールドにパラメータを割り当てるだけで、RAIIはここでは使用できません。 2)可能であればtry-with-resourcesを使用してください(おそらくコンストラクタが "代入モード"でしか動作しない場合はもっと可能でしょう)。 3)複数の 'Closeable'インスタンスを1つのインスタンスに結合する' Closeable'デコレータを書くことができます。 4)あるいは、あなたはGuava 'com.google.common.ioを使うことができます。より近くに。 –