Object Cloning in Java
In Java, object cloning refers to the process of creating a duplicate copy of an object. This allows you to create a new object with the same state (i.e., field values) as the original object. Cloning is particularly useful in scenarios where you want to create a copy of an object without modifying the original one, such as when you need to create backup copies or work with objects in a thread-safe manner.
What is Object Cloning?
Object cloning in Java can be achieved using the clone()
method, which is provided by the Object
class. By default, the clone()
method performs a shallow copy of the object, meaning that it copies the reference values of the fields. If the fields themselves are references to other objects, those references are copied, not the actual objects.
To make use of cloning, the class must implement the Cloneable
interface. This is a marker interface that indicates to the JVM that it is safe to clone instances of that class.
Shallow Copy vs. Deep Copy
Shallow Copy: The cloned object contains references to the same objects as the original object. Changes made to nested objects will affect both the original and cloned object.
Deep Copy: The cloned object contains copies of the objects referenced by the original object. Changes made to nested objects in the clone will not affect the original object.
Using the clone()
Method
Shallow Cloning: When you implement the
clone()
method in a class that implementsCloneable
, Java creates a shallow copy of the object.Deep Cloning: You can override the
clone()
method to perform deep cloning, where you manually clone the objects referenced by the original object.
Example of Object Cloning (Shallow Copy)
class Person implements Cloneable {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // Performs shallow copy
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class TestCloning {
public static void main(String[] args) {
try {
Person person1 = new Person("Alice", 25);
Person person2 = (Person) person1.clone(); // Cloning person1
System.out.println("Original: " + person1);
System.out.println("Cloned: " + person2);
// Modifying the cloned object
person2.name = "Bob";
person2.age = 30;
System.out.println("\nAfter modifying cloned object:");
System.out.println("Original: " + person1);
System.out.println("Cloned: " + person2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
Output:
Original: Person [name=Alice, age=25]
Cloned: Person [name=Alice, age=25]
After modifying cloned object:
Original: Person [name=Alice, age=25]
Cloned: Person [name=Bob, age=30]
Explanation:
The
Person
class implementsCloneable
and overrides theclone()
method.A shallow copy of
person1
is created and stored inperson2
.Modifying the
name
andage
of the cloned object does not affect the original object, as it is a shallow copy of the object (the fields themselves are primitive data types, so they are copied directly).
Deep Cloning Example
To perform a deep copy, you need to override the clone()
method to clone the fields that are references to other objects as well.
class Address implements Cloneable {
String city;
String state;
public Address(String city, String state) {
this.city = city;
this.state = state;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class PersonWithAddress implements Cloneable {
String name;
Address address;
public PersonWithAddress(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// Deep cloning the address field
PersonWithAddress clonedPerson = (PersonWithAddress) super.clone();
clonedPerson.address = (Address) address.clone(); // Cloning the address field
return clonedPerson;
}
@Override
public String toString() {
return "PersonWithAddress [name=" + name + ", address=" + address.city + ", " + address.state + "]";
}
}
public class TestDeepCloning {
public static void main(String[] args) {
try {
Address address = new Address("New York", "NY");
PersonWithAddress person1 = new PersonWithAddress("Alice", address);
PersonWithAddress person2 = (PersonWithAddress) person1.clone(); // Deep cloning person1
System.out.println("Original: " + person1);
System.out.println("Cloned: " + person2);
// Modifying the cloned object's address
person2.address.city = "Los Angeles";
person2.address.state = "CA";
System.out.println("\nAfter modifying cloned object:");
System.out.println("Original: " + person1);
System.out.println("Cloned: " + person2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
Output:
Original: PersonWithAddress [name=Alice, address=New York, NY]
Cloned: PersonWithAddress [name=Alice, address=New York, NY]
After modifying cloned object:
Original: PersonWithAddress [name=Alice, address=New York, NY]
Cloned: PersonWithAddress [name=Alice, address=Los Angeles, CA]
Explanation:
In this example, the
PersonWithAddress
class performs deep cloning by cloning theaddress
field.After modifying the
address
of the cloned object, the original object's address remains unchanged, demonstrating that a deep copy was made.
Key Points About Cloning:
Shallow Copy: Only the top-level object is cloned, and references to other objects are copied (not the objects themselves).
Deep Copy: All objects referenced by the original object are also cloned, ensuring no shared references between the original and the cloned object.
Cloneable Interface: To allow cloning in Java, the class must implement the
Cloneable
interface. If the class does not implement this interface, callingclone()
will throw aCloneNotSupportedException
.CloneNotSupportedException: This exception is thrown if the class does not implement
Cloneable
and you attempt to clone an object.
Conclusion
Object cloning is a powerful technique in Java for creating copies of objects, but it requires careful consideration of the type of copy you need: shallow or deep. By using the clone()
method and understanding the concepts of shallow and deep cloning, you can manage object copies effectively in your programs.
Subscribe to my newsletter
Read articles from Mohammed Shakeel directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Mohammed Shakeel
Mohammed Shakeel
I'm Mohammed Shakeel, an aspiring Android developer and software engineer with a keen interest in web development. I am passionate about creating innovative mobile applications and web solutions that are both functional and aesthetically pleasing.