延迟加载Singleton - 将静态字段调用导致实例化

时间:2015-06-10 04:12:40

标签: java singleton

根据定义,我有以下所谓的延迟加载单例:

public class MySingleton {

    public static String myTrigger="a trigger";

    private MySingleton(){
    }

    private static enum LazyLoad {
        IMDB_LOOKUP_INSTANCE;
        private static final IMDB_LOOKUP = new MySingleton();
    }

    public static MySingleton getInstance() {
        return LazyLoad.IMDB_LOOKUP_INSTANCE.IMDB_LOOKUP;
    }
}

当我打这样的电话时会发生什么:

String someString = MySingleton.myTrigger;

单身人士不会被实例化吗?

3 个答案:

答案 0 :(得分:1)

你的枚举有问题。所以,我修改了它,下面的代码工作并初始化MySingleton

public class MySingleton {

public static String myTrigger="a trigger";

private MySingleton(){
    System.out.println("Initialized");
}

private static enum LazyLoad {

    IMDB_LOOKUP_INSTANCE(new MySingleton());

    MySingleton value;

    LazyLoad(MySingleton value){
        this.value = value;
    }

    private MySingleton getValue(){
        return this.value;
    }

}

public static MySingleton getInstance() {
    return LazyLoad.IMDB_LOOKUP_INSTANCE.getValue();
}
}

当您调用MySingleton.myTrigger时,类会被加载。但是如果你希望你的MySingleton在类加载时被初始化,那么将MySingleton.getInstance()放在静态块中。

答案 1 :(得分:0)

在致电mrb_undef_value()之前,您的单身人士不会被实例化。

答案 2 :(得分:0)

在测试之后(通过在构造函数中放置一个print语句),我发现了 -

在上面的代码中,实例化不会发生,直到调用MySingleton.getInstance()

但是如果你将静态MySingleton对象作为类的直接属性而不是枚举内部,它将在调用MySingleton.myTrigger时实例化,这是因为在加载类时会实例化所有静态字段

但是在enum的情况下,enum不是类的静态属性,它只在访问时加载。

我也测试过这样的东西 -

class MySingleton {

public static String myTrigger="a trigger";

    private MySingleton(){
        System.out.println("Printing");
    }

    public static enum LazyLoad {
        IMDB_LOOKUP_INSTANCE;
        public static final String Hello = "Hello";
        private static final MySingleton IMDB_LOOKUP = new MySingleton();
    }

    public static MySingleton getInstance() {
        return LazyLoad.IMDB_LOOKUP_INSTANCE.IMDB_LOOKUP;
    }
}

在上面,对MySingleton.LazyLoad.IMDB_LOOKUP_INSTANCE.Hello的调用也会导致MySingleton对象的实例化。