Reputation: 3714
I am reading about Singleton design pattern and evaluating different implementations. I have doubt with the below implementations:
A. Singleton Implementation with static inner class
public class SingletonWithStaticClass {
private SingletonWithStaticClass(){}
private static class SingletonInnerClass{
public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass();
}
public static SingletonWithStaticClass getInstance(){
return SingletonInnerClass.INSTANCE;
}
}
B. Singleton double checked locking
public class SingletonWithDoubleCheck {
private static SingletonWithDoubleCheck INSTANCE = null;
private SingletonWithDoubleCheck(){
if(INSTANCE != null){
throw new RuntimeException("Accessing private constructor is prohibited. Use getInstance method instead");
}
}
public static SingletonWithDoubleCheck getInstance(){
if(INSTANCE == null){
synchronized (SingletonWithDoubleCheck.class) {
if(INSTANCE == null){
INSTANCE = new SingletonWithDoubleCheck();
}
}
}
return INSTANCE;
}
}
Which one is better?
I feel we can access the private constructor with Reflection in first implementation where as second implementation is safe (From Reflection attack).
However, I am not going to use any of these in my production code, I will use enum instead. But out of these two, isn't the first implementation is broken when considered Reflection attack?
Please correct me if my understanding is wrong.
Upvotes: 4
Views: 1192
Reputation: 65811
Neither are good - and attempting to compare them using different scales is counter-productive.
The first is unnecessarily complex and, as you say, is open to reflection hacking, but so is the other one, just slightly less so.
The second uses a synchronized
which comes with a cost.
Upvotes: 1
Reputation: 533530
Both are overly complicated. The first was the best option before Java 5.0, however the second was never a good option. It didn't work before Java 5.0, it requires a volatile
field and after this version you could use enum
I prefer using an enum
to define a class with exactly one instance. It is a final
class, thread safe, lazy loaded, and has a private
constructor.
enum Singleon {
INSTANCE;
}
The double locking singleton is only useful if you must provide configuration information in it's construction. In this case, I prefer to use Dependency Injection to provide/configure singletons and only have stateless Singletons which don't require configuration.
Upvotes: 6