Is there a reason to keep a reference to a Singleton instance in another class in Java?
This is probably a pretty dumb question, but earlier today I ran into some code where an external class was storing a reference to a Singleton class instance (in a private field), and was using this re开发者_高级运维ference instead of getting the instance from the Singleton class every time.
At first it looked like bad design to me, because it adds a field to a class for nothing, but is there another reason why you shouldn't do this (or should do this)?
Small code example to illustrate:
enum SomeSingletonObject {
INSTANCE;
public void someMethod() {...}
}
class AnotherObject {
private SomeSingletonObject sso;
public AnotherObject() {
this.sso = SomeSingletonObject.INSTANCE;
}
public void someMethod() {
sso.someMethod();
// instead of
// SomeSingletonObject.INSTANCE.someMethod();
}
}
In this example, no, there is no benefit.
However, if you are using dependency injection where your class takes its dependencies as constructor arguments, passing in a singleton instance could be very useful, and in that case you would have no option but to store the reference.
The first reason that comes to mind is to make it easy to substitute with some other object, one that implements a common interface or extends a common superclass.
In addition, it is possible that two instances of a singleton exist if loaded by different class loaders.
Also, though not exactly in he spirit of the singleton pattern, it could be used to store a reference to an old instance of the singleton object.
If you can guarantee that the given singleton really is a singleton this approach will work. In a more complex environment it may fail, e.g.:
public class Singleton {
private static Singleton instance = new Singleton();
public static Singleton instance() {
if (someCondition == true) {
Singleton.instance.close() // close the object
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
The above example is not really a singleton, but it will break the code you provided as a new reference has been assigned to instance
. Those problems may occur if you use external libraries without understanding/access to their internal behaviour.
I'd avoid 'caching' a reference to a singleton.
Actually I can seem some benefit in this in that if you are using an enum with a constructor to manage the static reference it will be initialized on startup (like on class load) and can never change after that.
This can be possible beneficial for separating out permgen classes which may improve hot deploying to containers where that is an issue. However I have no idea if this is actually the case.
On the negative side you might loose lifecycle management of the static reference if the enum is doing the initialization.
The better solution is to generally avoid static singletons like this and rely on dependency injection or AOP (Google Spring's @Configurable).
精彩评论