静态字段和单例的麻烦

时间:2012-01-24 12:39:13

标签: java singleton

我有两个班级:

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始终为空

问题为什么?

2 个答案:

答案 0 :(得分: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或服务定位器模式,而不是手动实现单例行为。

答案 1 :(得分:1)

您应该在第一次调用getInstance()时创建单例实例,而不是静态创建。无论依赖周期如何,这都可以。

public class Singleton {
  private static Singleton instance = null;

  private Singleton(){...}

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