次のようなコード(簡略化)があります。
class A {
B b = new B();
void close() {
b.close();
}
}
class B {
Closeable mustBeClosed = new Closeable() {
{
System.out.println("create");
}
@Override
public void close() {
System.out.println("close");
}
};
int n = 0 / 0;
void close() {
mustBeClosed.close();
}
}
//code
try (A a = new A()) {
//do something
}
mustBeClosed が解放されることを保証する方法は?
これは、オブジェクト階層が複雑な場合に発生する可能性があります。B のファイナライズをオーバーライドすることは、完全な解決策ではない可能性があります。
この問題に対するベストプラクティスまたは原則はありますか?
改訂版は次のようになります。
class B {
Closeable mustBeClosed;
B() {
try {
mustBeClosed = ...
//other initialization which might raise exceptions
} catch (throwable t) {
close();
throw t;
}
}
void close() {
if (mustBeClosed != null) {
try {
mustBeClosed.close();
} catch (Throwable t) {
}
}
//all other resources that should be closed
}
}
ただし、これにはコードが多すぎて、洗練されたものとは言えません。さらに、所有権階層内のすべてのクラスが同じスタイルに従う必要があるように思われるため、大量のコードが生成されます。
何かアドバイス?