单身人士 - 正确的方式

时间:2011-04-20 19:14:59

标签: java singleton

public enum YourSingleton {
    INSTANCE;

    public void doStuff(String stuff) {
        System.out.println("Doing " + stuff);
    }
}

YourSingleton.INSTANCE.doStuff("some stuff");

这是原始链接, http://electrotek.wordpress.com/2008/08/06/singleton-in-java-the-proper-way/

我在问我们为什么可以在Java中以这种方式调用函数doStuff。

4 个答案:

答案 0 :(得分:5)

在Java中,enum可以执行class可以 [1] 的所有操作。 YourSingleton.INSTANCE创建了一个YourSingleton的实例,因此您可以调用方法,就好像它是一个常规的class实例一样,基本上就是这样。

有关枚举类型的更深入讨论,请参阅官方Java文档:http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

[1] enum没有实际的继承实现。由于所有enum类型都隐含继承java.lang.Enum而Java不支持多重继承,因此您无法扩展其他任何内容。

答案 1 :(得分:2)

实现单例的传统方法很好,但是为了将其状态保持为真正的单例,它需要保护自己免受复杂的序列化和反射攻击。这样做的一般方法是使类实现Serializable,使所有实例字段Transient并实现readResolve方法。 (返回相同的单例实例)。

Enum Singleton模式提供开箱即用的所有这些功能。但主要原因是,我喜欢Enum变体是它的可读性。根据我的说法,它以比传统单身人士更简洁的方式传达它所做的事情。(你不必向新开发者解释,所有涉及序列化的变幻莫测以及序列化如何打破单身保证以及为什么你需要readResolve方法等等。)

答案 2 :(得分:0)

我知道这不是你要求的,但这就是我需要一个班级成为单身人士的时候,这可能会有所帮助。我创建了一个静态getInstance方法,该方法创建并返回该类的新实例(如果不存在)或者返回其自身的现有引用,并且我将此类的构造函数设为private。

例如:

public class NameOfClass{
    private static NameOfClass variableReferencingThisClass=new NameOfThisClass();

    private NameOfClass(){}

    public static NameOfClass getInstance(){
        return variableReferencingThisClass;
    }
}

答案 3 :(得分:0)

您也可以使用双锁单例创建。假设类为MyObject,则具有private构造函数,并且声明的static字段instance为null。然而,这并不能保证2个单身人士最终不会被创造出来,但与单次检查相比,这是一个更接近线性安全的尝试。

public static MyObject getInstance()
{
  if (instance == null)
  {
    synchronized(MyObject.class) {  
      if (instance == null)          
        instance = new MyObject(); 
    }
  }
  return instance;
}