Declaration of Cloneable Interface in Java
To declare a class as cloneable in Java, you need to implement the Cloneable interface. Let’s see how you can declare the Cloneable interface in a class:
public class MyClass implements Cloneable {
// Class members and methods
}
By adding the `implements Cloneable` clause to the class declaration, you are indicating that objects of this class can be cloned. The Cloneable interface does not define any methods, so there are no additional methods to implement in the class.
However, implementing the Cloneable interface alone is not sufficient to perform cloning. You also need to override the `clone()` method from the Object class to provide the actual cloning logic.
For example:
public class MyClass implements Cloneable {
// Class members and methods
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
In this example, the `clone()` method is overridden in the MyClass. The `super.clone()` statement invokes the clone() method of the superclass (Object class) to create a shallow copy of the object. If the class contains any mutable objects or references, you may need to perform additional steps to create a deep copy of those objects to ensure a complete and independent clone.
It's important to note that the `clone()` method is declared to throw a `CloneNotSupportedException`. This exception is thrown if the class does not implement the Cloneable interface, which indicates that cloning is not supported for objects of that class.
Examples of Cloneable Interface in Java
Let's look at a few examples to understand how the Cloneable interface can be used in Java:
Example 1: Cloning a Simple Object
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// Getters and setters
}
// Usage
Person person1 = new Person("Rahul", 25);
Person person2 = (Person) person1.clone();
In this example, the Person class implements the Cloneable interface & overrides the `clone()` method. The `clone()` method simply calls `super.clone()` to create a shallow copy of the Person object. The cloned object `person2` will have the same name & age as `person1`.
Example 2: Cloning an Object with References
public class Address implements Cloneable {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// Getters and setters
}
public class Employee implements Cloneable {
private String name;
private Address address;
public Employee(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
public Object clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
cloned.address = (Address) address.clone();
return cloned;
}
// Getters and setters
}
// Usage
Address address = new Address("123 Street", "City");
Employee employee1 = new Employee("Rahul", address);
Employee employee2 = (Employee) employee1.clone();
In this example, the Employee class has a reference to an Address object. To create a deep copy of the Employee object, the `clone()` method is overridden to clone both the Employee object & its associated Address object. This ensures that `employee1` & `employee2` have independent copies of the Address object.
Deep Copy Using clone() Method
In Java, the `clone()` method performs a shallow copy by default, which means that only the top-level object is copied, and any referenced objects are shared between the original and the cloned object. However, in some cases, you may want to create a deep copy, where the referenced objects are also cloned to achieve complete independence between the original and the cloned object.
To create a deep copy using the `clone()` method, you need to override the `clone()` method in your class and manually clone the referenced objects.
For example:
public class Department implements Cloneable {
private String name;
public Department(String name) {
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// Getters and setters
}
public class Employee implements Cloneable {
private String name;
private Department department;
public Employee(String name, Department department) {
this.name = name;
this.department = department;
}
@Override
public Object clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
cloned.department = (Department) department.clone();
return cloned;
}
// Getters and setters
}
// Usage
Department department = new Department("Engineering");
Employee employee1 = new Employee("Rahul", department);
Employee employee2 = (Employee) employee1.clone();
employee2.getDepartment().setName("Marketing");
System.out.println(employee1.getDepartment().getName()); // Output: Engineering
System.out.println(employee2.getDepartment().getName()); // Output: Marketing
In this example, the Employee class has a reference to a Department object. To create a deep copy of the Employee object, the `clone()` method is overridden to clone both the Employee object and its associated Department object.
In the `clone()` method of the Employee class, `super.clone()` is called to create a shallow copy of the Employee object. Then, the `department` field of the cloned Employee object is explicitly cloned by calling the `clone()` method on the original `department` object.
By cloning the Department object separately, any modifications made to the `department` of `employee2` will not affect the `department` of `employee1`. This ensures that `employee1` and `employee2` have independent copies of the Department object.
Note: Creating a deep copy using the `clone()` method requires careful understanding of all the referenced objects in your class. You need to manually clone each referenced object to achieve a complete deep copy.
Frequently Asked Questions
Can any Java class be cloned?
No, only classes that implement the Cloneable interface can be cloned using the `clone()` method. Attempting to clone an object of a class that does not implement Cloneable will throw a CloneNotSupportedException.
What is the difference between a shallow copy and a deep copy?
A shallow copy creates a new object but shares the same references as the original object for any referenced objects. A deep copy creates a new object and recursively clones all the referenced objects, resulting in a completely independent copy.
Is the Cloneable interface a functional interface?
No, the Cloneable interface is a marker interface. It does not define any methods and serves only as a tag to indicate that a class allows cloning of its objects.
Conclusion
In this article, we talked about the Cloneable interface in Java, which allows objects to be cloned. We learned how to declare a class as cloneable by implementing the Cloneable interface and overriding the `clone()` method. We also saw examples of cloning simple objects and objects with references.
You can also check out our other blogs on Code360.