Что лучший способ состоит в том, чтобы разработать 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();
}
Еще раз спасибо.
Используйте статический инициализатор и повторно вызовите исключение
как ExceptionInInitializerError
. Щелкните ссылку, чтобы прочитать Javadoc, и вы увидите, что он подходит именно для этого конкретного функционального требования: обработки исключений во время статической инициализации . Синглтон на самом деле представляет собой не что иное, как статически и лениво инициализированный глобальный объект.
private static class SingletonObjectFactoryHolder{
private static final ObjectFactory INSTANCE;
static {
try {
INSTANCE = new ObjectFactory();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
}
Нет необходимости в идиоме блокировки с двойной проверкой , которая считается анти-шаблоном и в некоторых случаях даже небезопасна.
Просто не бросайте исключение из конструктора объекта. Вы можете предоставить метод init ()
и выбросить исключение оттуда, если это необходимо.
Вы можете проверить наличие null INSTANCE внутри getInstance и лениво инициализировать его. Но обычно лучше, если конструкторы не бросают, если вы можете сделать конструктор более безопасным, это, вероятно, будет лучше всего.
Я согласен с 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.
}
}