Preventing Cloning in Singleton Design Pattern
This is our third article on Singleton Design Pattern. The purpose of the singleton class is to control object creation, limiting the number of objects to only one.
In our previous two articles, we have discussed how we can create Singleton Design Pattern in Single-threaded and multithreaded environment.
In this article, we will discuss how we can prevent creating more than one instance in case our Singleton class has implemented Cloneable interface.
What is Object Cloning?
The object cloning is a way to create exact copy of an object. So if somebody will clone our singleton instance, it will create another copy of the Singleton instance which violates principle of Singleton Design Pattern.
How does Java support Cloning?
In java, clone() method of Object class is used for cloning. clone() is protected method and as every class in java by default extends Object class, object of any class including our Singleton class can call clone() method.
If somebody will call instance.clone()
method, will it create copy of our Singleton class?
No. The java.lang.Cloneable interface
must be implemented by the class whose object clone we want to create. If we don’t implement Cloneable interface, clone()
method generates CloneNotSupportedException
.
So, if we are not implementing
Cloneable
interface in our Singleton class, then we do not require to prevent cloning. Java will do it for us.
What if our Singleton class is inherriting properties of some class which has implemented cloneable interface?
For example,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class CloneableParent implements Cloneable { } class SingletonChild extends CloneableParent { private static SingletonChild instance = new SingletonChild(); private SingletonChild() { } public static SingletonChild getInstance() { return instance; } // clone() method code here } |
Well, in this case we need to override clone() method inside SingletonChild
and throw CloneNotSupportedException
explicitly as shown below:
1 2 3 4 | @Override protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } |
The above is only necessary if a superclass of a singleton class implements a public clone() method.
What if parent class has already overriden clone() method, and it is not throwing CloneNotSupportedException?
CloneNotSupportedException
is a checked exception and as parent class method is not throwing CloneNotSupportedException
, we can not throw it from our SingletonChild. Here is the code for your reference :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class CloneableParent implements Cloneable { @Override protected Object clone() { try{ return super .clone(); }
{ System.out.println(“Swallowing Exception.”); } } } class SingletonChild extends CloneableParent { private static SingletonChild instance = new SingletonChild(); private SingletonChild() { } public static SingletonChild getInstance() { return instance; } @Override protected Object clone() throws CloneNotSupportedException { // Compilation error throw new CloneNotSupportedException(); } } |
You will get compilation error on line 20. In such cases, you should throw RunTimeException and change method singnature as shown in below code snippet:
1 2 3 4 | @Override protected Object clone() { throw new RuntimeException( "Clone Not Supported" ); } |
Download Complete Java Program »
Next Article in the series of Singleton Design Pattern : Serialization and Singleton Design Pattern
That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.
Happy Learning 🙂
If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.
We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.
About the Author
Tags: Cloning, Core Java, Creational Design Patterns, Design Patterns, Java, Singleton, Singleton Design Pattern
Comments and Queries
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:<pre><code class="java"> String foo = "bar"; </code></pre>For more information on supported HTML tags in disqus comment, click here.