2012-01-24 13 views
7

Tengo dos clases:El problema con el campo estático y Singleton

public class Singleton{ 
    private Singleton(){...} 

    private static class InstanceHolder{ 
     private static final Singleton instance=new Singleton(); 
    } 

    public static Singleton getInstance(){ 
     return InstanceHolder.instance; 
    } 
} 

y

public class Someclass{ 
    private static final Singleton singleton=Singleton.getInstance(); 

    public static Singleton getSingleton(){ 
     return singleton; 
    } 
} 

Problema

Si alguna parte (en realidad, en otro constructor de la clase Singleton) que utilizo algo como esto:

private final Singleton singleton=Someclass.getSingleton(); 

mi singleton siempre nula

Pregunta ¿Por qué?

+0

¿Funciona si lo haces fuera de un constructor? – Vadim

Respuesta

8

Su ejemplo funciona bien, por lo tanto está incompleto.

Tal vez en su aplicación real que tiene un ciclo de dependecy entre sus clases, por lo que getSingleton() se invoca antes de que se complete la inicialización de Someclass, algo así como lo siguiente, pero con múltiples clases involucradas:

public class Foo { 
    private static Foo INSTANCE = new Foo(); // Prints null 
    private static String s = "foo"; 

    public Foo() { 
     System.out.println(s); 
    } 
} 

Es especialmente probablemente si tienes múltiples singletons interdependientes implementados de esta manera. Trate de encontrar y elminar estos ciclos.

Además, quizás sería mejor utilizar algún tipo de patrón DI o Service Locator en lugar de implementar el comportamiento singleton manualmente.

1

Debe crear la instancia de singleton en la primera llamada al getInstance() en lugar de estáticamente. Esto funcionará independientemente de los ciclos de dependencia.

public class Singleton { 
    private static Singleton instance = null; 

    private Singleton(){...} 

    public static Singleton getInstance() { 
    if(instance == null) { 
     instance = new Singleton(); 
    } 
    return instance; 
    } 
} 
+0

En el autor de la clase 'Singleton' ya lo hace usando el idioma del titular estático. El problema está en otras clases. – axtavt

+0

Pero la instancia se crea estáticamente en la publicación original. En mi sugerencia, no lo es. Esto asegura que la instancia se crea después de todas las inicializaciones estáticas. (A menos que exista 'private static Singleton s = Singleton.getInstance()' en algún lugar. – tobiasbayer

+1

Creo que es mejor sincronizar getInstance. –

Cuestiones relacionadas