0

次のクラスがあるとしましょう

public class A {
   private B b;
}

B のインスタンスを作成するためのファクトリがありますが、作成者メソッドは例外をスローします。

public class BCreatorFactory {
   public static createB() throws SomeException {
      // DO the intialization
      // ...
      return b;
}

宣言行に Ab を設定すると、例外を処理する方法がありません

public class A {
   private B b = BCreatorFactory.createB() // BAD -> no way of dealing with the exception
}

コンストラクター内で Ab を設定すると、「半分焼かれた」インスタンスが作成されるか、再び例外がスローされ、呼び出し元のコードが適切に初期化されていないインスタンスを処理するように強制されます。

public class A {
   private B b;

   public A() {
      try {
         b = BCreatorFactory.createB();
      }
      catch (SomeException se) {
      // Do something, perhaps try to recover ? <- IMO also BAD
      }
   }
}

また

public class A {
   private B b;

   public A() throws SomeException { // BAD
      b = BCreatorFactory.createB();
   }
}

B のインスタンスを遅延初期化することができます。

public class A {
   private B b;

   public B getB() throws SomeException {
      if (b == null) {
          b = BCreatorFactory.createB(); // BAD -> not thread safe -> can result in redundant createB() invocations
      }
      return b;
   }
}

しかし、スレッドセーフにする唯一の方法は、Java の JVM 内で壊れていることが知られているDouble-Checked Lockingを使用することです。

public class A {
   private B b;

   public B getB() throws SomeException {
       if (b == null) {
            synchronized(this) {
                if (b == null) {
                    b = BCreatorFactory.createB(); // BAD -> not really thread safe -> broken
                }
            }
       }
       return b;
   }
}

では、辛抱強い読者の皆さん、私は何をすべきでしょうか?

言い換えれば、作成時に例外をスローする可能性のあるオブジェクトへの参照を含むオブジェクト インスタンスを初期化するための最良の解決策は何ですか?

4

2 に答える 2

0

コンストラクターが例外をスローしても問題はありません。Java フレームワークの多くのクラスは、コンストラクターから例外をスローします。状況を自動的に処理して解決する方法がある限り、コンストラクター内で例外をキャッチしても問題ありません。Java で例外をチェックするポイントは、エラー状態を単に無視することはできず、どこかでそれを処理する必要があることです。

例外をスローし、呼び出し元のコードが正しく初期化されていないインスタンスを処理するように強制します

呼び出し元のコードは、不適切に初期化されたインスタンスを処理する必要はありません。自動的に catch ブロックに移動し、例外をスローする、ログに記録する、失敗するなど、例外について何かを行う必要があります。

于 2011-11-24T16:21:23.663 に答える