Java实例成员初始化会引发异常

时间:2011-11-24 15:42:54

标签: java multithreading member-initialization

我们说我有以下课程

public class A {
   private B b;
}

现在有一个用于创建B实例的工厂,但创建者方法会抛出异常

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

如果我在声明行中设置了A.b,那么我将无法处理异常

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

如果我在构造函数中设置了A.b,那么我要么有一个“半烘焙”实例,要么再次抛出异常并强制调用代码处理未正确初始化的实例

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();
   }
}

我可以尝试延迟init 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中被破坏 双重检查锁定

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

那么,亲爱的患者读者,我应该做什么?

换句话说,初始化包含对创建对象的引用的对象实例的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:3)

这有什么问题?

public class A {
   private B b;

   public A() throws SomeException { // BAD -- *no it's not*
      b = BCreatorFactory.createB();
   }
}

构造函数抛出异常没有错。

答案 1 :(得分:0)

构造函数抛出异常没有任何问题。 Java框架中的许多类都会从构造函数中抛出异常。只要您有自动处理和解决情况的方法,它也可以在构造函数中捕获异常。在Java中检查异常的要点是,你不能忽略错误条件,你必须在某处处理它。

  

我抛出异常并强制调用代码来处理未正确初始化的实例

调用代码不必处理不正确初始化的实例,它将自动转到catch块,在那里你应该对异常做一些事情,无论是抛出它,记录它,失败等等。