Item 3 of Josh Block's Effective Java (Enforce the Singleton Property With a Private Constructor or an Enumerator) mentions that "While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton."
Example:
public enum Elvis {
INSTANCE;
private final String[] favoriteSongs =
{ "Hound Dog", "Heartbreak Hotel" };
public void printFavorites() {
System.out.println(Arrays.toString(favoriteSongs));
}
}
Continued: "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."
The biggest negative I see is: aren't enums not supposed to have mutable state? It seems common to use a Singleton with state.
So has this pattern actually become more common since the publication date (2nd Edition published 2008)?
Singleton With EnumSince enums are inherently serializable, we don't need to implement it with a serializable interface. The reflection problem is also not there. Therefore, it is 100% guaranteed that only one instance of the singleton is present within a JVM.
By default, the Enum instance is thread-safe, and you don't need to worry about double-checked locking. In summary, the Singleton pattern is the best way to create Singleton in Java 5 world, given the Serialization and thread-safety guaranteed and with some line of code enum.
The singleton pattern restricts the instantiation of a class to one object. INSTANCE is a public static final field that represents the enum instance. We can get the instance of the class with the EnumSingleton. INSTANCE but it is better to encapsulate it in a getter in case if we want to change the implementation.
No, you can not create enum instances outside of the Enum boundary, because Enum doesn't have any public constructor, and the compiler doesn't allow you to provide any public constructor in Enum.
While enums aren't generally given mutable state, this fact is based on assumptions of how an enum is going to be used. While these assumptions usually hold, they don't always, and one such case where they do not is in the creation of a Singleton.
While it's not the most common use of enums, it's perfectly legitimate to have an enum with a mutable state, though you may want to indicate this fact in your code so any other programmer who might be looking at it don't get confused.
As for a popularity of this design pattern, I've seen it fairly often, but not so much that I'd say it has become "common."
(This answer presumes that an "enforced" singleton is really what you want, as opposed to a de facto singleton managed by your DI framework (e.g. Guice's @Singleton
), which is probably more often the right idea.)
To decompose your question into two: Is it really widely adopted? No, not as widely as it should be. Is it a good idea? Yes!
A Java enum is a class that can have only a fixed set of N instances, which are hardcoded in the source.
A singleton is a class that can have only a fixed set of N instances, which are hardcoded in the source. And N == 1.
It's as simple as that!
Enums can have mutable state. It's usually not a good idea because the nature of an enum is to have exactly X versions of a Type Y where X is larger than 1, so juggling around state (other than using fields/properties) becomes a bit of a nightmare as each method needs to take into account all possible state of all X enum constants.
But if you are going to define an enum with only one constant anyway; you can simply treat that single constant as an ordinary object and make all the assumptions that come with it. IOW: the problem of having X versions of state goes away because X is now 1.
No enum
s are not supposed to have mutable state. Statics should not usually be mutable. Singletons are just ways to obfuscate mutable statics. (Stateless objects that implement an interface are another matter.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With