Singleton e Exceção

Qual é a melhor maneira de projetar uma class singleton que poderia lançar uma exceção?

Aqui eu tenho um Singleton (usando o método de Bill Pugh, documentado em Wiki for 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; } 

Se uma exceção é lançada em 2, gostaria de propagá-lo para o chamador. No entanto, não posso lançar uma exceção da linha 1.

Então, é minha única opção para retornar um object nulo se o object singleton não foi criado corretamente?

obrigado

PS Eu percebo que este Singleton pode quebrar se for carregado por meio de diferentes carregadores de class ou se carregado de forma reflexiva, mas é bom o suficiente para o meu propósito.

//ATUALIZAR

Estou curioso, não posso reorganizar meu design como abaixo para lançar exceções?

Além disso, não preciso de nenhuma synchronization (o carregador de class garante que a class interna estática será carregada apenas uma vez e somente quando getInstance () for chamado). Assim, thread-safe e instanciado de forma lenta?

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

Obrigado novamente.

Use um inicializador estático e repita a Exception como ExceptionInInitializerError . Clique no link para ler o Javadoc, você verá que é adequado para este requisito funcional específico: manipular exceções durante a boot estática . Um singleton é na verdade nada menos do que um object global inicializado estaticamente e lazily.

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

Não há necessidade de idioma de bloqueio duplo verificado que é considerado um anti-padrão e, em algumas circunstâncias, até mesmo inseguro.

Apenas não jogue exceção do construtor do object. Você pode fornecer o método init () e lançar sua exceção de lá se for necessário.

Você pode verificar se há null INSTANCE dentro de getInstance e inicializá-lo com lentidão. Mas normalmente é melhor se os construtores não jogarem, se você puder tornar o construtor mais seguro que provavelmente seria o melhor.

Eu concordo com Arne Burmeister, o código para isso seria:

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