如何在Java中创建一个不可变的单例?

时间:2011-02-03 14:43:15

标签: java singleton immutability

不可变对象仅由其构造函数初始化,而单例由静态方法实例化。如何在Java中创建一个不可变的单例?

4 个答案:

答案 0 :(得分:8)

  

而单例由a实例化   静态方法

虽然这是通常的做法,但这绝不是唯一的方法。

在Java 1.5中,新版本的Singleton是枚举单例模式:

public enum Elvis{

INSTANCE // this is a singleton, no static methods involved

}

由于枚举可以包含构造函数,方法和字段,因此可以为它们提供所需的所有不可变状态。

参考:


此外,Singleton这个词留下了一些解释空间。 Singleton意味着每个定义的范围只有一个对象,但范围可以是很多东西:

  • Java VM 类加载器(感谢@PaŭloEbermann提醒我):在这种情况下使用enumsinitialize-through-static-inner-class pattern。这当然是单身人士的意思 小心:如果通过多个类加载器加载,枚举和所有其他单例都会被破坏。
  • 企业应用程序(在这种情况下,您需要一个容器管理的单例,例如Spring singleton bean)。这可以是每个VM的多个对象,也可以是每个VM的一个对象(当然,每个VM一个对象)
  • 主题(使用ThreadLocal
  • 请求 / 会话(同样,您需要一个容器来管理它,SpringSeam,其他几个人也可以为你)
  • 我忘了什么吗?

以上所有内容都可以变为不可变的,每个都以自己的方式(尽管容器管理的组件通常不容易)

答案 1 :(得分:5)

Sean指出的解决方案是初始化单身人士的好方法如果他们的创作并不昂贵。如果您想要“延迟加载”功能,请查看按需初始化持有者习惯用法。

 // from wikipedia entry
 public class Singleton {

   // Private constructor prevents instantiation from other classes
   private Singleton() {
   }

   /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
   private static class SingletonHolder { 
     public static final Singleton INSTANCE = new Singleton();
   }

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

 }

答案 2 :(得分:1)

public enum MySingleton {
instance;
//methods
}

//usage
MySingleton.instance.someMethod();

答案 3 :(得分:1)

你是不必要的复杂。要成为不可变的对象,一旦创建它就必须是不可修改的。这通常被解释为“仅在构造函数中可修改”,但如果您要创建另一种仍然使其不可变的方式。只要您的对象在初始化后无法修改,那么它就是不可变的。您可以考虑将Singleton实例设置为初始化的一部分。

不可变性的大多数好处与单身人士无关。