Item 3 in the 2nd Edition of Effective Java explains three ways of implementing a singleton in Java, the last of which is “Enum as Singleton”. This uses an Enum with a single element as a simple and safe way to provide a singleton. It’s stated as being the best way to implement a singleton (at least, for Java 5 onwards and where the additional flexibility of the “static factory method” approach isn’t required).
But is this technique a good or bad idea? Is anyone actually doing it this way? If you’ve used it or encountered it, are you happy with it or do you have any reservations?
Please note: I’m not interested in any wars over whether singletons are evil or not. The concept exists, one comes across them in real code, and there are reasonable discussions to be had over whether they are always a bad idea or have their uses in particular situations. None of that is relevant to how best to implement a singleton if one ever does wish to do so, or the pros and cons of different implementation techniques.
OK, with that dispensed with, what should we make of the “Enum as Singleton” technique?
From my point of view, it works, the code is trivially simple, and it does automatically take care of the “serialization” issue (that is, maintaining one instance per classloader even in the face of serialization and deserialization of the instance). But it feels too much like a trick, and (arguably) not in the spirit of the concept of an enumeration type. When I see an Enum that isn’t being used to enumerate a set of constants and that only has one element, I think I’m more likely to have to stop and figure out what’s going on rather than immediately and automatically thinking “oh, here’s a singleton”. If it becomes more common I’ll no doubt get used to seeing this idiom, but if so I might then find myself misled by any “normal” enumeration that just happens to only have one element.
Another concern is that whilst the use of a static factory method to provide a singleton offers more flexibility than either the use of a public static member or a single-element Enum, it requires different client code for accessing the singleton. So using either of the latter two approaches means that you risk having to change client code if you ever need to “upgrade” the singleton to the more flexible “static factory method” approach.
A further issue is how best to name Enum classes and instances that are implementing singletons. Should one stick to the usual naming conventions for Enums, or adopt some other naming convention (and maybe include “Singleton” in the name to make the intent clear)? And what if the singleton object is mutable in any way? Or is that a more general issue over the naming of enumeration “constants” if they are actually mutable? Or maybe it makes more sense to say that Enums must be genuine constants and should never, ever be mutable – in which case “Enum as Singleton” shouldn’t be used for any singleton with mutable state, which limits its applicability even more?
So now that the “Enum as Singleton” technique has been widely known for a few years, does anyone have any significant experiences from real-world use of it? Or any other opinions on this technique?