In Java, object copying is a crucial concept that allows you to create a new instance of an existing object. This can be useful when you want to modify the original object without affecting its copy or when you need to pass an object to a method without modifying the original object. In this tutorial, we will explore different techniques for copying objects in Java.
Shallow Copying
Shallow copying involves creating a new instance of the same class and copying all the fields to the new instance. The Object
class provides a clone()
method that supports shallow copying. However, using clone()
can be tricky, as it requires implementing the Cloneable
interface and overriding the clone()
method.
public class DummyBean implements Cloneable {
private String dummy;
public DummyBean(String dummy) {
this.dummy = dummy;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
To create a shallow copy of an object, you can use the clone()
method as follows:
DummyBean dum = new DummyBean("foo");
try {
DummyBean dumtwo = (DummyBean) dum.clone();
} catch (CloneNotSupportedException e) {
// Handle exception
}
Deep Copying
Deep copying involves creating a copy of an object along with all the objects it references. One way to achieve deep copying is by using Java Object Serialization.
import org.apache.commons.lang.SerializationUtils;
public class DummyBean implements Serializable {
private String dummy;
public DummyBean(String dummy) {
this.dummy = dummy;
}
}
// Create a deep copy of the object
DummyBean dumtwo = (DummyBean) SerializationUtils.clone(dum);
Another way to achieve deep copying is by using reflection.
private static Object cloneObject(Object obj) throws Exception {
Object clone = obj.getClass().newInstance();
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
if (field.get(obj) == null || Modifier.isFinal(field.getModifiers())) {
continue;
}
if (field.getType().isPrimitive() || field.getType().equals(String.class)
|| field.getType().getSuperclass().equals(Number.class)
|| field.getType().equals(Boolean.class)) {
field.set(clone, field.get(obj));
} else {
Object childObj = field.get(obj);
if (childObj == obj) {
field.set(clone, clone);
} else {
field.set(clone, cloneObject(field.get(obj)));
}
}
}
return clone;
}
Copy Constructors
Copy constructors are a simple way to create a copy of an object. A copy constructor is a constructor that takes another instance of the same class as a parameter.
public class DummyBean {
private String dummy;
public DummyBean(DummyBean another) {
this.dummy = another.dummy;
}
}
// Create a copy of the object using the copy constructor
DummyBean dumtwo = new DummyBean(dum);
Defensive Copying
Defensive copying involves creating a copy of an object to prevent modifications to the original object.
public class DummyBean {
private String dummy;
public DummyBean(String dummy) {
this.dummy = dummy;
}
public String getDummy() {
return new String(dummy); // Defensive copy
}
}
Conclusion
In conclusion, object copying in Java can be achieved using various techniques such as shallow copying, deep copying, copy constructors, and defensive copying. Each technique has its own advantages and disadvantages, and the choice of which one to use depends on the specific requirements of your application.