224

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()?

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
Anand
  • 20,708
  • 48
  • 131
  • 198

6 Answers6

245

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.

Hearen
  • 7,420
  • 4
  • 53
  • 63
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 24
    You should add that by default enums have implicit private constructor and that explicitly adding a private constructor is not needed unless you actually have code that you need to run in that constructor – Nimrod Dayan Apr 11 '16 at 14:10
  • each enum field creates an instance only once, so no need to create private constructor. – Pravat Panda Jul 26 '16 at 05:45
  • 2
    public enum MySingleton { INSTANCE,INSTANCE1; } and then System.out.println(MySingleton.INSTANCE.hashCode()); System.out.println(MySingleton.INSTANCE1.hashCode()); it prints different hashcodes. Does it mean two objects of MySingleton are created ? – scott miles Oct 26 '16 at 17:30
  • 1
    @scottmiles Yes. Because you have two instances. A singleton, by definition, has one. – Elliott Frisch Oct 27 '16 at 03:06
  • The `private` modifier has no meaning for an `enum` constructor and is entirely redundant. – Dmitri Nesteruk Nov 15 '17 at 16:48
  • @XetraSu It's safe in the sense that there will only be one instance (regardless of how many caller's invoke `getInstance()` in threads). – Elliott Frisch Apr 01 '18 at 16:28
  • Source of the information: [Effective Java Item 3](https://www.oreilly.com/library/view/effective-java-3rd/9780134686097/). A highly-recommended reading. A summary of the book can be found at https://github.com/HugoMatilla/Effective-JAVA-Summary. – koppor Oct 19 '19 at 07:59
100

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).

Hearen
  • 7,420
  • 4
  • 53
  • 63
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
75

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.

ekostadinov
  • 6,880
  • 3
  • 29
  • 47
  • I think, to make a singleton testable you could use a strategy pattern and have all the singleton's actions go through the strategy. So you can have one "production" strategy and one "testing" strategy... – Erk Jul 30 '18 at 11:18
9

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
8

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.

Erk
  • 1,159
  • 15
  • 9
7

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.

Deepika R
  • 3
  • 4
Bruno Franco
  • 2,028
  • 11
  • 20