The first of your methods is a common way to try to implement a lazily-created singleton. It has some issues such as lack of thread safety, although they can be overcome via mechanisms like synchronization.
The second of your methods is truly vile. Exceptions should only be used to indicate exceptional conditions in the code. If you don't want somebody to create an instance of the class, don't let them - you can take control of the instantiation. Forcing them to catch an exception is a totally unnecessary burden on users of your class. (And it's not thread safe either).
A single-element enum
is the best and easiest way to create a singleton.
However, there are certain circumstances in which you can't use an enum
, for instance if your class needs to extend another class:
If you can initialize the instance eagerly, just do that:
class Singleton /* extends Blah */ {
private static final Singleton INSTANCE = new Singleton();
static Singleton getInstance() { return INSTANCE; }
}
If you want to defer initialization until it is required, you can use the lazy holder idiom:
class Singleton /* extends Blah */ {
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
static Singleton getInstance() {
return Holder.INSTANCE;
}
}
The Holder
class is not initialized until getInstance()
is called, so the Singleton
instance is not created until then.
It should be noted that singletons are considered by some to be a design antipattern.