How to prevent Singleton Pattern from Reflection and Cloning
Posted By : Sudhir Kumar Ojha | 17-Dec-2018
In Object Oriented Programming (OOP), singleton design pattern allows you to create only one instance(Object) of class at a time. It is a part of creational design patterns. Here are the following important points about singleton pattern:
- Singleton classes can have only one instance i.e. one object per class and that instance should be globally accessible.
- java.lang.Runtime and java.awt.Desktop 2 singleton internal classes provided by JVM.
- Singleton class design pattern is a type of creational design pattern.
- We should take care of outer classes should be prevented to create an instance of a singleton class.
To create a singleton class:
- Make constructor of class as private.
- Create a static method that returns the return type object of the singleton class. The lazy initialization concept is used to achieve this.
Prerequisites
java 1.5 or later
Notepad or Notepad++ (Or any text editor you want)
or Eclipse IDE (Any version)
For example:
package com.oodles.test;
class Singleton
{
public static Singleton singleton = null;
private Singleton()
{
// private constructor
}
public static Singleton getInstance()
{
if( singleton == null)
{
singleton = new Singleton();
}
return singleton;
}
}
Now create class name Test to test that above implementation. In the following Test class, I have created two instances of Singleton class by using getInstance() method of Singleton class because getInstance() method is a static method hence we can call this method by using the class name. For example consider the following code snippet:
package com.oodles.test;
public class Test
{
public static void main( String[] arguments)
{
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println( "Hash code of singleton1 = "+ singleton1.hashCode() );
System.out.println( "Hash code of singleton2 = "+ singleton2.hashCode() );
}
}
Output:
But by using Reflection, and Cloning we can create multiple objects of the Singleton class. Consider the following:
1. Using Reflection:
for ( Constructor constructor : constructors )
{
// Below code will destroy the singleton pattern
constructor.setAccessible( true );
instance1 = ( Singleton ) constructor.newInstance();// Here you will be able to create multiple instances.
break;
}
Overcome reflection issue: To overcome reflection issue raised by reflection, enums are used because java ensures internally that enum value is instantiated only once. In Java, Enums are special types and globally accessible, they can be used for singletons. Its only disadvantage is that it is not flexible i.e it does not allow lazy initialization.
//Java program for Enum type singleton
public enum Test
{
INSTANCE;
}
2. By using cloning:
By using cloning we can create multiple instances of that class. Using clone we can create a copy of the object. Consider the following example:
package com.oodles.test;
class SuperClass implements Cloneable
{
@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
// Singleton class
class Singleton extends SuperClass
{
// public instance initialized when loading the class
public static Singleton instance = new Singleton();
private Singleton()
{
// private constructor
}
}
public class Test
{
public static void main( String[] arguments) throws CloneNotSupportedException
{
Singleton singleton1 = Singleton.instance;
Singleton singleton2 = (Singleton) singleton1.clone();
System.out.println("Hash code of singleton1 = "
+ singleton1.hashCode());
System.out.println("Hash code of singleton1 = "
+ singleton2.hashCode());
}
}
Output:
There are two different hashCode that means two different objects of the singleton class.
Overcome clone issue: To overcome the object clone issue, just override the clone() method in Singleton class and throw CloneNotSupportedException. Whenever we try to use
package com.oodles.test;
class SuperClass implements Cloneable
{
@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
// Singleton class
class Singleton extends SuperClass
{
// public instance initialized when loading the class
public static Singleton instance = new Singleton();
private Singleton()
{
// private constructor
}
@Override
protected Object clone() throws CloneNotSupportedException
{
throw new CloneNotSupportedException();
}
}
public class Test
{
public static void main( String[] arguments) throws CloneNotSupportedException
{
Singleton singleton1 = Singleton.instance;
Singleton singleton2 = ( Singleton ) singleton1.clone();
System.out.println( "Hash code of singleton1 = " + singleton1.hashCode() );
System.out.println( "Hash code of singleton1 = " + singleton2.hashCode() );
}
}
Output:
Reference:
For more info please visit https://www.geeksforgeeks.org/prevent-singleton-pattern-reflection-serialization-cloning/
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Sudhir Kumar Ojha
Sudhir Kumar Ojha is having skills to work as Software developer & having good knowledge of Java.