Josh Bloch recommends using a single-element enum
type to implement singletons (see Effective Java 2nd Edition, Item 3: Enforce the singleton property with a private constructor or an enum type).
Some people think this is a hack, since it doesn't clearly convey intent, but it does work.
The following example is taken straight from the book.
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
Here is his closing arguments:
This approach [...] is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiations, 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.
On enum
constant singleton guarantee
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 (§15.9.1).
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.
On lazy initialization
The following snippet:
public class LazyElvis {
enum Elvis {
THE_ONE;
Elvis() {
System.out.println("I'M STILL ALIVE!!!");
}
}
public static void main(String[] args) {
System.out.println("La-dee-daaa...");
System.out.println(Elvis.THE_ONE);
}
}
Produces the following output:
La-dee-daaa...
I'M STILL ALIVE!!!
THE_ONE
As you can see, THE_ONE
constant is not instantiated through the constructor until the first time it's accessed.
return new Singleton()
toinstance = new Singleton()
– aioobeSingleton.getInstance( )
. In 99% of cases there should be no other reasons to load Singleton class without calling itsgetInstance
method. If theinstance
isstatic final
then it will be initialized when Singleton class is loaded, period, and will be thread safe. WhileLazyHolder
pattern does work I think it's unnecessary overkill and an anti-pattern, as well as singleton is anti-pattern itself.</RANT> – Alexander PogrebnyakgetInstance
right away. Without this call there is absolutely no need to load a singleton class. – Alexander Pogrebnyak