ejemplo - java singleton example
Singleton y Exception (4)
Estoy de acuerdo con Arne Burmeister, el código para eso sería:
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.
}
}
¿Cuál es la mejor manera de diseñar una clase de singleton que podría lanzar una excepción?
Aquí tengo un Singleton (utilizando el método de Bill Pugh, documentado en Wiki para 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;
}
Si se lanza una excepción a 2, me gustaría propagarla a la persona que llama. Sin embargo, no puedo lanzar una excepción de la línea 1.
Entonces, ¿es mi única opción devolver un objeto nulo si el objeto singleton no se creó correctamente?
Gracias
PD: Me doy cuenta de que este Singleton puede romperse si se carga a través de diferentes cargadores de clases o si se carga por reflejo, pero es lo suficientemente bueno para mi propósito.
//ACTUALIZAR
Tengo curiosidad, ¿no puedo reorganizar mi diseño como se muestra a continuación para lanzar excepciones?
Además, no necesito ninguna sincronización (el cargador de clases garantiza que la clase interna estática solo se cargará una vez y solo cuando se llame a getInstance). Por lo tanto, hilo-seguro y perezosamente instanciado?
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();
}
Gracias de nuevo.
Puede comprobar si hay INSTANCE nulo dentro de getInstance e inicializarlo con pereza. Pero normalmente es mejor si los constructores no lanzan, si puede hacer que el constructor sea más seguro, probablemente sería lo mejor.
Simplemente no lance la excepción del constructor del objeto. Puede proporcionar el método init ()
y lanzar su excepción desde allí si es necesario.
Utilice un inicializador estático y vuelva a emitir la Exception
como ExceptionInInitializerError
. Haga clic en el enlace para leer el Javadoc, verá que se adapta exactamente a este requisito funcional particular: manejo de excepciones durante la inicialización estática . Un singleton es de hecho nada más o menos que un objeto global estático y perezosamente inicializado.
private static class SingletonObjectFactoryHolder{
private static final ObjectFactory INSTANCE;
static {
try {
INSTANCE = new ObjectFactory();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
}
No es necesario un lenguaje de bloqueo de doble control, que se considera un antipatrón y, en algunas circunstancias, incluso inseguro.