3

次のようなコード(簡略化)があります。

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
    }
}

ただし、これにはコードが多すぎて、洗練されたものとは言えません。さらに、所有権階層内のすべてのクラスが同じスタイルに従う必要があるように思われるため、大量のコードが生成されます。

何かアドバイス?

4

2 に答える 2

0

ラッパー メソッドを使用して、すべてのCloseableインスタンスを正常に閉じます。

closeGraceFully(Closeable c) { // call this guy for all instances of closeable
   try{
       c.close();
   } catch(IOException ex) {
      // nothing can be done here, frankly.
  }
}

次に、このラッパー メソッドを呼び出します。close()直接電話しないでください。finalizersそれらは悪であり、アプリの速度を低下させるため、使用しないでください。

于 2015-09-16T07:03:14.487 に答える