Navin Israni Navin Israni - 2 months ago 5
Java Question

Why does accessor method of the object in Singleton Design Pattern have to be "static?

In singleton design pattern, we restrict creation of objects to a single object using private constructor.

To provide a global handle to it, we use a "public static" method.

My question is why static is needed here? Why not just public?

Answer

Short answer:

Assume you have a Singleton class:

public class Singleton {
    ...
}

Then the constructor is probably private which means you cannot use new Singleton() from another class.

So the only way to access something that is inside the Singleton class would be using Singleton.methodName() or Singleton.fieldName.

But in order to do this then these methods and fields cannot be part of an object, they have to be static. And the getSingleton() or getInstance() method is no exception.

Answer with examples:

Assume you have a Singleton class:

public class Singleton {

}

We can now add the constructor. But it can not be public, since if it is public then you can just use new Singleton() from every other class and then it would not be a Singleton anymore. So the class would now look like this.

public class Singleton {

    private Singleton(){

    }

}

Now that the constructor is private this means that you cannot instantiate the class from another class it can also be instantiated from inside the Singleton class. So we should add the getInstance() or getSingleton() method.

public class Singleton {

    private Singleton(){

    }

    public Singleton getSingleton(){
        return null;
    }

}

But now we cannot access it since the getSingleton() method can only be used on an object and we cannot instantiate a Singleton object from outside the class. So the getSingleton() needs to be accessed by using Singleton.getSingleton() and therefore it has to become a static method.

public class Singleton {

    private Singleton(){

    }

    public static Singleton getSingleton(){
        return null;
    }

}

The answer so far should answer the question but it is not a functional Singleton class. So please continue reading for the complete answer.

Now we also want to return the instance of the Singleton from the getSingleton() method. So we also want a field called instance of singleton to point to the instance of the Singleton class.

public class Singleton {
    private Singleton instance;

    private Singleton(){

    }

    public static Singleton getSingleton(){
        return instance;
    }

}

But now the instance field is not accessible by the get getSingleton() method since the way the class is written right now the instance is a field of an the object and not the class, so the instance field has to become static as well.

public class Singleton {
    private static Singleton instance;

    private Singleton(){

    }

    public static Singleton getSingleton(){
        return instance;
    }

}

And now the final problem is that the variable instance is not instantiated anywhere so it will always return null. So we have to check in the getSingleton() that if the instance is null then create a new Singleton() and make the instance field point to it.

public class Singleton {
    private static Singleton instance;

    private Singleton(){

    }

    public static Singleton getSingleton(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }

}

If you want a thread safe Singleton class you can use something like this instead (suggested by Boris the Spider):

public enum Singleton {
    INSTANCE;
    private Singleton(){
        // TODO
    }    
}

And now the Singleton is complete.