Singleton pattern using enum type

For any application, we need to be highly conscious about creation and deletion of objects, since it takes huge memory which leads to junks and errors.

Knowing the complexity of maintaining objects, we can opt for using a Singleton design pattern where the class is instantiated only once. Lets look at how to build such a class and all of its constraints.

Now, how to create a singleton class in Java?

Singleton is used when we need to design a component that is unique such as a task manager. There are three ways of implementing a singleton class.

  1. Implementation : Using a private constructor and public static member access.
  2. // Singleton with public final field
    public class ClassName{
    public static final ClassName INSTANCE = new ClassName();
    private ClassName() { ... }
    }

  3. Implementation :Using  lazy initialization and a static factory method to get the instance. Factory method approach gives you the flexibility of changing the class from singleton without changing its API. Lazy initialization means the object gets initialized only when the method is called and not when the class is instantiated.
  4. // Singleton with static factory and lazy intiialization
    public class ClassName{
    public static final ClassName INSTANCE;
    private ClassName() { ... }
    public static ClassName getInstance() {
    if(INSTANCE==null)
    INSTANCE= new ClassName();
    return INSTANCE;
    }
    }

  5. Implementation : Using one-element-enum. Enums in java are used only when a variable can take one out of small set of possible values. You may ask how this enums come into creation of singletons. The answer is “Enum fields are compile time constants, but instances of the enum type.The Enum semantics guarantees that there will be only one instance. The instance is constructed when the enum type is referenced for the first time.”
  6. public enum ClassName{   INSTANCE;   }
    This will render the same result as in Implementation 1. Using enums is more concise and provides serialization machinery for free and ironclad guarantee against multiple instantiation even in serialization(while de-serializing) and reflection attacks(calling the instantiation method or constructor)

What if the clone() method is called on the class object?

In this case, we have to throw a cloneNotSupportedException by implementing the Cloneable interface with the help of clone() method.
public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); }

How can we prevent new object creation in the de-serializing process when enums are not used?

Declare all instance fields transient and provide readResolve method after implementing Serializable interface. This is taken care while using via enums.
// readResolve method to preserve singleton property
private Object readResolve() {
// Return the one true ClassObject and let the garbage collector
return INSTANCE;
}

Sounds easy right. To sum it up, use Enums to create singletons where you need one, it is the best way to do it.

Read “Effective Java” book to dig deeper. Happy coding.