How to prevent Singleton Pattern from Reflection, Deserialization and Cloning ?
source link: http://adnjavainterview.blogspot.com/2019/07/how-to-prevent-singleton-pattern-from-reflection-serialization-cloning-injava.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How to prevent Singleton Pattern from Reflection, Deserialization and Cloning ?
There are mainly 3 concepts which can break singleton property of a singleton class. We can discuss how it can break and how to prevent from above concepts as below.
- Reflection
Example to show how reflection can break the singleton pattern:-
Singleton.java,
package com.example.demo; public class Singleton { private static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
package com.example.demo; import java.lang.reflect.Constructor; public class ReflectionSingleton { public static void main(String[] args) {
Singleton objOne = Singleton.getInstance(); Singleton objTwo = null; try { Constructor constructor = Singleton.class.getDeclaredConstructor(); constructor.setAccessible(true); objTwo = (Singleton) constructor.newInstance(); } catch (Exception ex) { System.out.println(ex); } System.out.println("Hashcode of Object 1 - "+objOne.hashCode()); System.out.println("Hashcode of Object 2 - "+objTwo.hashCode()); } }
Hashcode of Object 1 - 366712642
Hashcode of Object 2 - 1829164700
private Singleton() throws Exception { if (instance != null) { throw new RuntimeException("Instance already exists"); } }
- Deserialization
Below code is to illustrate how Singleton pattern breaks,
package com.example.demo; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; public class DeserializationSingleton { public static void main(String[] args) throws Exception { Singleton instanceOne = Singleton.getInstance(); ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file.text")); out.writeObject(instanceOne); out.close(); ObjectInput in = new ObjectInputStream(new FileInputStream("file.text")); Singleton instanceTwo = (Singleton) in.readObject(); in.close(); System.out.println("hashCode of instanceOne is - " + instanceOne.hashCode()); System.out.println("hashCode of instanceTwo is - " + instanceTwo.hashCode()); } }
Output:-
hashCode of instanceOne is - 1550089733
hashCode of instanceTwo is - 2003749087
As we see above output, there are two objects got created because hashcodes of instanceOne and instanceTwo are different, hence it breaks singleton principle.
Prevent Singleton Pattern from Deserialization:-
To overcome this issue, we need to override readResolve() method in Singleton class and return same Singleton instance.
Singleton.java,
@override
protected Object readResolve() { return instance; }
hashCode of instanceOne is - 1550089733
hashCode of instanceTwo is - 1550089733
- Cloning
Singleton.java
..... @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } ....
package com.example.demo; public class CloningSingleton { public static void main(String[] args) throws CloneNotSupportedException, Exception { Singleton instanceOne = Singleton.getInstance(); Singleton instanceTwo = (Singleton) instanceOne.clone(); System.out.println("hashCode of instance1 - "+instanceOne.hashCode()); System.out.println("hashCode of instance2 - "+instanceTwo.hashCode()); } }
Output:-
hashCode of instance1 - 366712642
hashCode of instance2 - 1829164700
If we see above output, two instances have different hascodes means these instances are not same.
Prevent Singleton Pattern from Cloning:-
In the above code, breaks the Singleton principle i. e created two instances. To overcome above issue we need to implement/override clone() method and throw an exception i.e CloneNotSupportedException from clone method. If anyone try to create clone object of Singleton, it will throw an exception as see below code.
Singleton.java
...... @Override protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } ........
Thank you for visiting blog...
Related Posts:--
1) Singleton Design Pattern in java with example
2) Factory Design Pattern in Java
3) Builder Design Pattern in Java
Recommend
-
44
The singleton pattern is definitely the easiest pattern of all the design patterns, but trust me — many of us are doing wrong. So, let’s...
-
33
Today, we are going to discuss how to create a singleton instance for a clustered (or) cloud environment. What The singleton instance is a class that has exactly one instance at any given time....
-
10
Java设计模式—单例设计模式(Singleton Pattern)完全解析 转载请注明出处:
-
6
Singleton Pattern First things first: if you’re still reading this blog, thanks! I haven’t posted anything since last December; it has been a rough first h...
-
7
The Singleton Pattern In TypeScriptWhat is the Singleton pattern and when to use it.
-
8
Reading Time: 3 minutes Overview In this article, I will be sharing the working of a singleton pattern, in a nutshell, using a simple real-world example. 1. Singleton Design Pattern The aim of the singleto...
-
21
singleton is design-pattern or anti-pattern? ...
-
5
Introduction This series is going to be dedicated to the basic understanding of Java. When ever I find myself asking, "How does this work ?". I will create a blog post and put it here. This series will not be in order so...
-
4
Design pattern: singleton, prototype and builder by Christophe | updated: April 12, 2016 | posted: June 21, 2015
-
4
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK