While I agree with Andy Turner's answer to avoid singletons if possible, I'll add this for completeness: the static synchronized getInstance method is a relic from the past. There are at least 3 singleton pattern implementations that don't require that.
a) eager singleton
public class EagerSingleton{
private EagerSingleton(){}
private static final EagerSingleton INSTANCE = new EagerSingleton();
public static EagerSingleton getInstance(){ return INSTANCE; }
}
This is initialized at class-load time, whenever you reference the class EagerSingleton in any way (e.g. by declaring a variable of that type).
b) lazy singleton
public class LazySingleton{
private LazySingleton(){}
private static class Holder{
private static final LazySingleton INSTANCE = new LazySingleton();
}
public static LazySingleton getInstance(){ return Holder.INSTANCE; }
}
This is initialized at call time, the first time you call the method getInstance(). The class loader now loads the holder class and initializes the INSTANCE field, and it's guaranteed to do that in a synchronized way. Use this version if your singleton has expensive setup, and is not always necessary.
c) enum Singleton
public enum EnumSingleton{
INSTANCE;
// and if you want, you can add the method, too, but it's
// unnecessary:
public static EnumSingleton getInstance(){ return INSTANCE; }
}
Enum items are compile-time constants, i.e. their uniqueness is guaranteed at compile-time, not only at runtime (at runtime, singletons are unique per class loader, and that applies to all versions). This is the best way to go, unless your requirements are to extend from an existing class.
The enum version gives you many other features for free:
- equals / hashCode / toString implementations out of the box
- defense against de-serialization attacks
- multiton support (just add another enum item)
So the next time you see somebody write the double-checked locking mechanism or similar, tell them they are being way too complicated and technical. Let the class loader do the work for you.
With all 3 versions: make sure the functionality you use is backed by an interface, and code against that interface, not the implementation type. That will make your code testable.
enumin which case I would writeMySingleton.INSTANCE.doSomething()- Peter Lawrey