What is singleton java class ? how to create singleton class in java ?

Photo by Scott Webb on Unsplash

What is singleton java class ? how to create singleton class in java ?

Definition :

If we create a class and then add some logic or feature to that class so that once we create an object of that class it will not allow us to create another object then that class is called a singleton Java class.

In short, a class that can have only one object and will not allow to create second object is called a singleton Java class.

How to create?

To create a singleton Java class. first, we have to understand in how many ways we can create objects in Java.

Below is the list of ways to create objects in Java which I am aware of.

  1. using the "new" keyword

  2. using class.forName()

  3. using factory method

  4. using clonable

  5. deserialization

  6. reflection API

Now to achieve singleton we have to control the process of object creation for that class so that we can create only one object and restrict further object creation.

From the above list, the factory method is the only way wher we can control everything as it is not predefined. so let's use it.

so in the factory method, we can add a condition that will check if there is an instance of the singleton class is available or not, based on the condition we can return the existing instance or a new instance.

Now initially there will be no objects to call that factory method so how to invoke/call that method? it is tricky, how about we make it static so that we don't need a object to invoke it. We just have to use the class name and we will make it public so that anyone can invoke/call it.

Now in a multithreaded environment, there is a possibility that thread-1 and thread-2 checked and found that there is no instance and then thread-1 creates the object and as thread-1 also checked previously and found there is no instance so thread-2 will create the object too. now we have two objects. we don't want that, what can we do to prevent that? well, we can make the method synchronized.

So basically the static factory method should look like this.

public static synchronized <class-name> getInstance() {
        if (instance == null) {
            instance = new SingletonClass();
        }
        return instance;
    }

Now that we have achieved how to create an object for a singleton class. But there are many other ways to create objects so we have to restrict that.

to prevent object creation outside the class through the "new" keyword, we can make the constructor private.

Making the constructor private can prevent "class.forName()" from creating an object too.

Now through reflection API someone can access the private constructor and create an object so we can throw an exception inside the constructor when there is already an object available. So the constructor will look like below.

private <class-name>() {
        if (instance != null) {
            throw new IllegalStateException("Singleton instance already created.");
        }
    }

Now we have to prevent object creation through deserialization (when our class is serializable). So now as we all know when we create an object through deserialization the readResolve() method is called(if implemented) before the deserialized object is returned.

So basically we can implement this method and return the existing object rather than the serialized object so the implementation will look like below.

protected Object readResolve() {
     return instance;
}

Now we have to prevent object creation through the "clone()" method, for that we can override the clone method and throw CloneNotSupportedException.

// Override clone to prevent cloning
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("Clone is not allowed.");
    }

Finally, we have covered all the points which I can think of. So let's see how our singleton class looks like.


import java.io.Serializable;

public class Singleton implements Serializable {
        private static final long serialVersionUID = 1L;

        private static Singleton instance;

        private Singleton() {
            // Private constructor to prevent instantiation
            if (instance != null) {
                throw new IllegalStateException("Singleton instance already created.");
            }
        }

                // Implement readResolve to prevent deserialization creating a new instance
        protected Object readResolve() {
            return instance;
        }

        // Override clone to prevent cloning
        @Override
        protected Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException("Clone is not allowed.");
        }

        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
        // Optional: Add other methods or properties as needed
}

Finally, we created the singleton class, let me know if you know any other ways or better ways to create a singleton class.

Did you find this article valuable?

Support Hemant Besra by becoming a sponsor. Any amount is appreciated!