Wednesday, October 3, 2012

Implementing Singleton in Java

A singleton class will always have at most one instance and so it will be instantiated only once.

There are two primary ways to implement it:
  • using public static method and 
  • using public factory method. 
Both the approaches make use of private constructor. As the constructor is private we will generally not be able to construct an instance of this calls using new operator. But a privileged  client can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method. So we can create an exception if it's asked to create a second instance.


Using public static field:

// Singleton with public final field
public class God{
   public static final God INSTANCE = new God();
   private God() { ... }
   public void worshipHIM() { ... }
}


Using public static factory method:

// Singleton with static factory
public class God{
   private static final God INSTANCE = new God();
   private God() { ... }
   public static God getInstance() { return INSTANCE; }
   public void worshipHIM() { ... }
}

One advantage of the latter approach is: we can remove the singleton constraint easily without changing the API, if we want. As of Java 1.5 there is one more approach as pointed by Joshua Bloch(Effective Java, Item 3) here.

// Enum singleton - the preferred approach
public enum God{
   INSTANCE;
   public void worshipHIM() { ... }
}

Implementing singleton using first two approaches may need some extra work if we also want the class to be serializable. We need to make all the fields transient and also need to provide readResolve method. If we don't do so we will get new instance each time we de-serialize a serialized instance. So we need to add the following method to GOD class:

// readResolve method to preserve singleton property
private Object readResolve() {
   // Return the one true God and let the garbage collector
   // take care of the God impersonator.
   return INSTANCE;
}

There is one third approach as well by using enum:

public enum God {
   INSTANCE;
  public void makeAMiracle() { ..... }
}

And this is the best approach.

More can be found here:









No comments: