Reputation: 19892
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)?
Upvotes: 20
Views: 4299
Reputation: 1777
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."
Upvotes: 10
Reputation: 45443
It's not a good idea.
It forces your class to inherit from a concrete class Enum
. That pollutes your type hierarchy.
The type of the INSTANCE
must be exactly Elvis
; it cannot be some subtype of Elvis
.
More generally you have no freedom to choose how the instance is instantiated.
And syntax-wise, is this really too much typing?
public class Elvis {
static public Elvis INSTANCE = new Elvis();
Upvotes: -4
Reputation: 147164
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.)
Upvotes: 1
Reputation: 40851
(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!
Upvotes: 8
Reputation: 11976
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.
Upvotes: 3