При инициализации члена экземпляра Java возникает исключение - PullRequest
0 голосов
/ 24 ноября 2011

Допустим, у меня есть следующий класс

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

Я мог бы попытаться отложить экземпляр 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;
   }
}

Но единственный способЯ могу подумать о том, чтобы сделать его поточно-безопасным с помощью , который, как известно, был взломан в JVM java Двойная проверка блокировки

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 ]

3 голосов
/ 24 ноября 2011

Что с этим не так?

public class A {
   private B b;

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

Нет ничего плохого в том, что конструктор выдает исключение.

0 голосов
/ 24 ноября 2011

Нет ничего плохого в том, что конструктор выдает исключение.Многие классы в среде Java выдают исключение из конструктора.Также можно ловить исключение внутри конструктора, если у вас есть способ автоматически обработать и разрешить ситуацию.Смысл проверенных исключений в Java заключается в том, что вы не можете просто игнорировать условие ошибки, и вам нужно где-то его обработать.

Я выбрасываю исключение и заставляю вызывающий код обрабатывать неправильно инициализированный экземпляр

Вызывающему коду не нужно иметь дело с неправильно инициализированным экземпляром, он автоматически перейдет в блок catch, где вы должны что-то делать с исключением, будь то его выброс, регистрация,сбой и т. д.

...