单例模式重新实现

时间:2017-05-28 09:08:45

标签: java

我有点困惑,让我们用Java:

public final class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
   }
}

我可以轻松地继续重建

Singleton one = new Singleton();
Singleton two = new Singleton();
Singleton three = new Singleton();
....

`

那么如果我可以继续重建,那么只保留一个实例的目的是什么?

3 个答案:

答案 0 :(得分:4)

请注意,示例中的构造函数是private,因此您无法创建该类的多个实例,只能使用getInstance()来获取该类的单个实例。 / p>

答案 1 :(得分:1)

您只能在单例类中创建单例,因为构造函数是私有的。如果要从该类外部访问singleton的属性和方法,可以使用getInstance来获取对现有单例的引用,而不是创建新的单例。

答案 2 :(得分:1)

首先,正如评论员所指出的那样,在决定天气之前要记住很多事情,单身人士是最好的方式,然后决定单身人士的实施:你的单身人士的实例化会变得沉重吗?是不会总是使用或者你应该推迟实例化直到你需要它?然后去懒惰的初始化,而不是枚举或你渴望的exaple;你的代码是多线程的吗?你的应用程序是分布在集群上的吗?你需要序列化实例吗? 多次使用单例不是最好的答案,它可能使测试和调试很难。这是a good article discussing when not to use singleton

如果你决定使用单例,那么你可以根据它的使用方式选择几个实现选项。请参阅此article describing various implementations and their drawbacks

回到你的问题:一个急切的初始化单例类,其序列化和线程安全性不是问题。作为类的设计者,您应该确保维护类的开发人员将按预期使用它,只调用一次构造函数。即使是在课堂内。

您可以改进代码,以便将来更改类的人明白构造函数只应调用一次。你可以这样做:

public final class Singleton {
private static final Singleton INSTANCE = new Singleton();

private Singleton() {
   if(INSTANCE != null){
      throw new RuntimeException("singleton constructor called twice");
   }
}

public static Singleton getInstance() {
    return INSTANCE;
   }
}

远离您的代码,您可以使用枚举创建它:

public enum Singleton {
    INSTANCE;
    private Singleton(){
          //initializing
    }
    //public methods
}