by BehindJava

How to break Singleton Design pattern in Java

Home » java » How to break Singleton Design pattern in Java

In this tutorial we are going to learn about breaking the singleton pattern in detail and refer this tutorial for detailed understanding of the Singleton Design pattern.

Now create a class named singleton and there are three important points to remember while creating a singleton class.

  1. Create a instance variable as private static and return type will be class itself.
  2. Make its constructor as private(So that no body is capable of creating the object of singleton class).
  3. Make the getInstance method with private and static so that it is capable of returning the singleton object and this is known as lazy loading.
public class Singleton {
    //1
	private static Singleton singleton_instance = null;
    //2
	private Singleton() {

	}
    //3
	public static Singleton getInstance() {
		if (singleton_instance == null) {
			singleton_instance = new Singleton();
		}
		return singleton_instance;
	}

}

Now create a class to break the singleton design pattern and create two instances of the singleton class to check whether the returned instance is same or different by printing the hash code method as shown below.

public class BreakSingletonBJ {

	public static void main(String[] args) {
		Singleton originalSingletonInstance = Singleton.getInstance();
		Singleton duplicateSingletonInstance = Singleton.getInstance();

		System.out.println("Hash Code for originalSingletonInstance is : " + originalSingletonInstance.hashCode());
		System.out.println("********");
		System.out.println("Hash Code for duplicateSingletonInstance is : " + duplicateSingletonInstance.hashCode());
	}
}

In the output we can see the hash code of both original and duplicate as one which means our singleton design pattern is properly implemented.

Hash Code for originalSingletonInstance is : 746292446
********
Hash Code for duplicateSingletonInstance is : 746292446

Breaking the Singleton Design Pattern

Now, We will break the singleton design pattern using the Reflection. This is the way where we can create the instance of Singleton design pattern with different hash codes that are stored at different memory locations which means we have successfully broken the Singleton Design Pattern.

  1. First thing is we need to catch hold is class using class.forName().
  2. Second is the constructor, we need to catch hold the constructor using getDeclaredC method.
  3. As we know the constructor is private, we need to make the constructor accessible to the main class using setAccessible as true.
  4. We are going to create new instance with the reflection as shown below.
package pract;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class BreakSingletonBJ {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
			InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

		Singleton originalSingletonInstance = Singleton.getInstance();
		Singleton duplicateSingletonInstance = Singleton.getInstance();

		System.out.println("Hash Code for originalSingletonInstance is : " + originalSingletonInstance.hashCode());
		System.out.println("Hash Code for duplicateSingletonInstance is : " + duplicateSingletonInstance.hashCode());

		Class<?> singletonClass = Class.forName("pract.Singleton");
		Constructor<Singleton> declaredConstructor = (Constructor<Singleton>) singletonClass.getDeclaredConstructor();
		Constructor<Singleton> constructor = declaredConstructor;
		constructor.setAccessible(true);

		Singleton brokenInstanceUsingReflection = constructor.newInstance();

		System.out.println("********");
		System.out.println("Hash Code for brokenInstanceUsingReflection is : " + brokenInstanceUsingReflection.hashCode());
	}
}

In the output we can see the change in hash code which means the Singleton Design pattern is broken.

Hash Code for originalSingletonInstance is : 746292446
Hash Code for duplicateSingletonInstance is : 746292446
********
Hash Code for brokenInstanceUsingReflection is : 1072591677

There is one more way to break the singleton design pattern i.e., with the Serialization.