lazy loaded Singleton - will a static field call cause instantiation

84 views Asked by At

i have the following what you might call a lazy loaded singleton per the definition:

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;
    }
}

What happens when i make a call like this:

String someString = MySingleton.myTrigger;

will the singleton not get instantiated ?

3

There are 3 answers

4
Anand S Kumar On BEST ANSWER

After testing (By putting a print statement in the constructor) , I found that -

In the above code, the instantiation will not occur untill the call to MySingleton.getInstance()

But if you put the static MySingleton object as a direct property of the class, instead of inside the enum , it will get instantiated on the call to MySingleton.myTrigger , this is because all static fields are instantiated when the class is loaded.

But in case of enum, enum is not a static property of the class, it is only loaded on access.

I tested something like this as well -

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;
    }
}

In the above , the call to MySingleton.LazyLoad.IMDB_LOOKUP_INSTANCE.Hello would also cause instantiation of MySingleton object.

0
fo_x86 On

Your singleton will not get instantiated until you call MySigleton.getInstance().

0
Ouney On

There are issues with your enum. So, i have modified it and the following code works and initializes 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();
}
}

Class gets loaded when you call MySingleton.myTrigger. But if you want your MySingleton to get initialized on class loading, put MySingleton.getInstance() in static block.