Cloning is the concept of creating the exact same copy. Java provides multiple ways to create exact replica of an existing object such as copy constructor
, method copying each field value into a new object or java.lang.Cloneable
interface clone
method. The clone
method is preferred because it saves the overhead of copying all the existing values and assigning them to a new object. The clone method is defined in the Object class.
By default Object
class clone method is protected, so the clone method will not be available to create multiple instances of the Singleton
class, it will give the error "The method clone() from the type Object is not visible"
But there might be a scenario where either Singleton
class is implementing java.lang.Cloneable
interface or extending superclass which implements java.lang.Cloneable
interface, then multiple copies of Singleton
class can be created.
package org.wesome.dsalgo.design.pattern.singleton;
import java.util.Objects;
public class Apple implements Cloneable {
static Apple appleInstance;
private Apple() {
System.out.println("Apple default constructor");
}
public static Apple getAppleInstance() {
System.out.println("Apple getAppleInstance");
if (Objects.isNull(appleInstance)) {
synchronized (Apple.class) {
if (Objects.isNull(appleInstance)) {
appleInstance = new Apple();
}
}
}
return appleInstance;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package org.wesome.dsalgo.design.pattern.singleton;
public class SingletonClass {
public static void main(String[] args) throws CloneNotSupportedException {
Apple apple = Apple.getAppleInstance();
System.out.println("apple = " + apple);
Apple apple1 = (Apple) apple.clone();
System.out.println("apple1 = " + apple1);
}
}
plugins {
id 'java'
id "io.freefair.lombok" version "6.4.1"
}
group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}
test {
useJUnitPlatform()
}
To prevent Singleton
object to be cloned multiple times, an Exception
can be thrown from the overridden clone method or the same instance can be returned as shown below.
package org.wesome.dsalgo.design.pattern.singleton;
import java.util.Objects;
public class Apple implements Cloneable {
static Apple appleInstance;
private Apple() {
System.out.println("Apple default constructor");
}
public static Apple getAppleInstance() {
System.out.println("Apple getAppleInstance");
if (Objects.isNull(appleInstance)) {
synchronized (Apple.class) {
if (Objects.isNull(appleInstance)) {
appleInstance = new Apple();
}
}
}
return appleInstance;
}
/* throw exception or call the getInstance method */
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Object cannot be cloned.");
}
}
package org.wesome.dsalgo.design.pattern.singleton;
public class SingletonClass {
public static void main(String[] args) throws CloneNotSupportedException {
Apple apple = Apple.getAppleInstance();
System.out.println("apple = " + apple);
Apple apple1 = (Apple) apple.clone();
System.out.println("apple1 = " + apple1);
}
}
plugins {
id 'java'
id "io.freefair.lombok" version "6.4.1"
}
group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}
test {
useJUnitPlatform()
}