2012-01-24 3 views
7

У меня есть два класса:Неприятности со статическим полем и одноточечного

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

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

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

и

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

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

Проблемные

Если где-то (на самом деле, в другом синглтон-конструктор класса), которые я использую что-то вроде этого:

private final Singleton singleton=Someclass.getSingleton(); 

мой singleton всегда нуль

Вопрос Почему?

+0

Это работает, если вы делаете это за пределами конструктора? – Vadim

ответ

8

Ваш пример отлично работает, поэтому он неполный.

Возможно, в вашем реальном приложении у вас есть цикл зависимых пакетов между вашими классами, так что getSingleton() вызывается до инициализации Someclass завершаются, что-то вроде следующего, но с несколькими классами, участвующими:

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

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

Это особенно вероятно, если у вас есть несколько взаимозависимых синглонов, реализованных таким образом. Попробуйте найти и устранить эти циклы.

Кроме того, возможно, было бы лучше использовать какой-либо шаблон DI или Service Locator вместо того, чтобы выполнять одноточечное поведение вручную.

1

Вы должны создать экземпляр singleton при первом вызове getInstance(), а не статически. Это будет работать независимо от циклов зависимостей.

public class Singleton { 
    private static Singleton instance = null; 

    private Singleton(){...} 

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

В авторском классе «Singleton» автор уже делает это, используя статическую икону владельца. Проблема в других классах. – axtavt

+0

Но экземпляр создается статически в исходном сообщении. По моему мнению, это не так. Это гарантирует, что экземпляр создается после всех статических инициализаций. (Если нет 'private static Singleton s = Singleton.getInstance()' где-то. – tobiasbayer

+1

Я думаю, что лучше сделать getInstance синхронизированным. –