Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an immutable singleton in Java?

An immutable object is initialized by its constuctor only, while a singleton is instantiated by a static method. How to make an immutable singleton in Java?

like image 706
chance Avatar asked Feb 03 '11 14:02

chance


3 Answers

while a singleton is instantiated by a static method

While this is the usual way of doing it, this is by no means the only way.

In Java 1.5 a new version of Singleton is the enum singleton pattern:

public enum Elvis{

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

}

And since enums can have constructors, methods and fields, you can give them all the immutable state you want.

Reference:

  • Java tutorial: Enum Types
  • Effective Java, Item 3
  • Singleton (the enum way) (WikiPedia)

Also, the term Singleton leaves some room for interpretation. Singleton means that there is exactly one object per defined scope, but the scope can be a number of things:

  • Java VM Classloader (thanks @Paŭlo Ebermann for reminding me): in this case use enums or the initialize-through-static-inner-class pattern. This is of course what is usually meant by a singleton.
    Be Careful: enums and all other singletons are broken if loaded through multiple Classloaders.
  • Enterprise Application (in this case you need a container-managed singleton, e.g. a Spring singleton bean). This can be several objects per VM or one object per several VMs (or one Object per VM, of course)
  • Thread (use a ThreadLocal)
  • Request / Session (again, you'll need a container to manage this, Spring, Seam and several others can do that for you)
  • did I forget anything?

All of the above can be made immutable, each in their own way (although it's usually not easy for container-managed components)

like image 183
Sean Patrick Floyd Avatar answered Sep 21 '22 00:09

Sean Patrick Floyd


The solution pointed out by Sean is a good way of initializing singletons if their creation is not expensive. If you want to "lazy loading" capability, look into the initialization on demand holder idiom.

 // 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;
   }

 }
like image 40
Sanjay T. Sharma Avatar answered Sep 20 '22 00:09

Sanjay T. Sharma


public enum MySingleton {
instance;
//methods
}

//usage
MySingleton.instance.someMethod();
like image 25
KitsuneYMG Avatar answered Sep 19 '22 00:09

KitsuneYMG