我们都知道这个古老的着名的lazy-init单身成语:
public class Singleton {
private static volatile Singleton instance;
private Singleton()
{
// init...
}
public static Singleton getInstance()
{
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
但是,下面的习惯用法本质上也是懒惰的,因为只有在第一次访问类时,实例才是init,由类加载器处理:
public class Singleton
{
private static final Singleton instance = new Singleton();
private Singleton()
{
// init..
}
public static Singleton getInstance()
{
return instance;
}
}
所以问题是,为什么我们要使用第一个例子而不是第二个例子呢? (并不是说使用spring等框架来管理对象的生命周期更好。)
即使您在另一个类中持有对单例的引用,例如:
public class Holder {
private int member1;
private int member2;
private Singleton myService = Singleton.getInstance();
}
无论我们采用哪种方法
,都会在加载Holder类时创建单例任何见解? 感谢
答案 0 :(得分:0)
这样的事情怎么样?
public class Singleton {
...
public static int getSomeStaticInfo() { return 42; }
...
}
public class Holder {
private int member1;
private int member2 = Singleton.getSomeStaticInfo();
private Singleton myService;
public void init() {
myService = Singleton.getInstance();
}
}
初始化单例时的行为在两个版本之间有所不同。这是版本1表现正确的(就我们说"懒惰"时所要求的)行为。仅仅因为你加载了这个类,并不意味着你想要它被初始化。