Singleton и исключение

Что лучший способ состоит в том, чтобы разработать singleton-класс, который мог выдать исключение?

Здесь у меня есть Singleton (использующий метод Bill Pugh, зарегистрированный в Wiki для Singleton).

    private static class SingletonObjectFactoryHolder{
    //1  
        private static final ObjectFactory INSTANCE = new ObjectFactory();
    }

    private ObjectFactory() throws Exception{
    //2
            //create the factory
    }


    public static ObjectFactory getInstance(){
    //3
        return SingletonObjectFactoryHolder.INSTANCE;
    }

Если бы исключение выдается в 2, я хотел бы распространить его вызывающей стороне. Однако я не могу выдать исключение от строки 1.

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

Спасибо

P.S. я действительно понимаю, что эта Singleton может повредиться, если ее загруженное через другой classloaders или, если загружено рефлексивно, но это достаточно хорошо для моей цели.

//ОБНОВЛЕНИЕ

Мне любопытно, разве я не могу перестроить свой дизайн как ниже для выдавания исключения?

Кроме того, мне не нужна никакая синхронизация (classloader гарантирует, что статический внутренний класс будет только загруженный однажды и только когда getInstance () назовут). Таким образом, ориентированный на многопотоковое исполнение и лениво инстанцированный?

 private static class SingletonObjectFactoryHolder{
        //1  
           public static ObjectFactory getInstance() throws Exception{
         return new ObjectFactory();
           }
 }

 private ObjectFactory() throws Exception{
        //2
        //create the factory
 }


 public static ObjectFactory getInstance(){
        //3
    return SingletonObjectFactoryHolder.getInstance();
 }

Еще раз спасибо.

30
задан CaptainHastings 18 February 2010 в 16:40
поделиться

4 ответа

Используйте статический инициализатор и повторно вызовите исключение как ExceptionInInitializerError . Щелкните ссылку, чтобы прочитать Javadoc, и вы увидите, что он подходит именно для этого конкретного функционального требования: обработки исключений во время статической инициализации . Синглтон на самом деле представляет собой не что иное, как статически и лениво инициализированный глобальный объект.

private static class SingletonObjectFactoryHolder{
    private static final ObjectFactory INSTANCE;
    static {
        try {
            INSTANCE = new ObjectFactory();
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}

Нет необходимости в идиоме блокировки с двойной проверкой , которая считается анти-шаблоном и в некоторых случаях даже небезопасна.

36
ответ дан 28 November 2019 в 00:16
поделиться

Просто не бросайте исключение из конструктора объекта. Вы можете предоставить метод init () и выбросить исключение оттуда, если это необходимо.

0
ответ дан 28 November 2019 в 00:16
поделиться

Вы можете проверить наличие null INSTANCE внутри getInstance и лениво инициализировать его. Но обычно лучше, если конструкторы не бросают, если вы можете сделать конструктор более безопасным, это, вероятно, будет лучше всего.

0
ответ дан 28 November 2019 в 00:16
поделиться

Я согласен с Arne Burmeister, код для этого будет выглядеть так:

private static class SingletonObjectFactoryHolder
{
    private static ObjectFactory INSTANCE;


    private ObjectFactory() 
    {

    }

    public static String getInstance() throws Exception
    {
      return (INSTANCE == null) ? (INSTANCE = new ObjectFactory()) : INSTANCE; 
     // A ternary operator might not be the best fit if you need to throw an exception, but I think it looks nicer than the if(INSTANCE==null){} else{} for lazy instantiation.
    }

}
-1
ответ дан 28 November 2019 в 00:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: