Implementing Singleton with an Enum (in Java)

JavaDesign PatternsEnumsSingleton

Java Problem Overview


I have read that it is possible to implement Singleton in Java using an Enum such as:

public enum MySingleton {
     INSTANCE;   
}

But, how does the above work? Specifically, an Object has to be instantiated. Here, how is MySingleton being instantiated? Who is doing new MySingleton()?

Java Solutions


Solution 1 - Java

This,

public enum MySingleton {
  INSTANCE;   
}

has an implicit empty constructor. Make it explicit instead,

public enum MySingleton {
	INSTANCE;
	private MySingleton() {
		System.out.println("Here");
	}
}

If you then added another class with a main() method like

public static void main(String[] args) {
	System.out.println(MySingleton.INSTANCE);
}

You would see

Here
INSTANCE

enum fields are compile time constants, but they are instances of their enum type. And, they're constructed when the enum type is referenced for the first time.

Solution 2 - Java

An enum type is a special type of class.

Your enum will actually be compiled to something like

public final class MySingleton {
    public final static MySingleton INSTANCE = new MySingleton();
    private MySingleton(){} 
}

When your code first accesses INSTANCE, the class MySingleton will be loaded and initialized by the JVM. This process initializes the static field above once (lazily).

Solution 3 - Java

In this Java best practices book by Joshua Bloch, you can find explained why you should enforce the Singleton property with a private constructor or an Enum type. The chapter is quite long, so keeping it summarized:

Making a class a Singleton can make it difficult to test its clients, as it’s impossible to substitute a mock implementation for a singleton unless it implements an interface that serves as its type. Recommended approach is implement Singletons by simply make an enum type with one element:

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

This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks.

>While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.

Solution 4 - Java

Like all enum instances, Java instantiates each object when the class is loaded, with some guarantee that it's instantiated exactly once per JVM. Think of the INSTANCE declaration as a public static final field: Java will instantiate the object the first time the class is referred to.

The instances are created during static initialization, which is defined in the Java Language Specification, section 12.4.

For what it's worth, Joshua Bloch describes this pattern in detail as item 3 of Effective Java Second Edition.

Solution 5 - Java

As has, to some extent, been mentioned before, an enum is a java class with the special condition that its definition must start with at least one "enum constant".

Apart from that, and that enums cant can't be extended or used to extend other classes, an enum is a class like any class and you use it by adding methods below the constant definitions:

public enum MySingleton {
    INSTANCE;

    public void doSomething() { ... }

    public synchronized String getSomething() { return something; }

    private String something;
}

You access the singleton's methods along these lines:

MySingleton.INSTANCE.doSomething();
String something = MySingleton.INSTANCE.getSomething();

The use of an enum, instead of a class, is, as has been mentioned in other answers, mostly about a thread-safe instantiation of the singleton and a guarantee that it will always only be one copy.

And, perhaps, most importantly, that this behavior is guaranteed by the JVM itself and the Java specification.

Here's a section from the Java specification on how multiple instances of an enum instance is prevented:

> An enum type has no instances other than those defined by its enum constants. It is a compile-time error to attempt to explicitly instantiate an enum type. The final clone method in Enum ensures that enum constants can never be cloned, and the special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization. Reflective instantiation of enum types is prohibited. Together, these four things ensure that no instances of an enum type exist beyond those defined by the enum constants.

Worth noting is that after the instantiation any thread-safety concerns must be handled like in any other class with the synchronized keyword etc.

Solution 6 - Java

Since Singleton Pattern is about having a private constructor and calling some method to control the instantiations (like some getInstance), in Enums we already have an implicit private constructor.

I don't exactly know how the JVM or some container controls the instances of our Enums, but it seems it already use an implicit Singleton Pattern, the difference is we don't call a getInstance, we just call the Enum.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnandView Question on Stackoverflow
Solution 1 - JavaElliott FrischView Answer on Stackoverflow
Solution 2 - JavaSotirios DelimanolisView Answer on Stackoverflow
Solution 3 - JavaekostadinovView Answer on Stackoverflow
Solution 4 - JavaJeff BowmanView Answer on Stackoverflow
Solution 5 - JavaErkView Answer on Stackoverflow
Solution 6 - JavaBruno FrancoView Answer on Stackoverflow