Introduction
Copying objects is a basic concept in Java that every developer should learn. When we create a copy of an object, we are creating a new object with the same state as the original. Java provides two main approaches for copying objects: shallow copying & deep copying. Shallow copying creates a new object that shares the same references as the original object, while deep copying creates a completely independent copy of the object & all its associated objects. In addition to these two methods, Java also supports the concept of cloning, which allows us to create a copy of an object using the clone() method.

In this article, we will discuss the concepts of shallow copying, deep copying, & cloning in Java. We will also look at proper examples to understand these concepts.
Methods of Copying
In Java, there are two primary methods for copying objects: shallow copying & deep copying. Let's explore each of these methods in more detail.
Shallow Copy
A shallow copy creates a new object that shares the same references as the original object. In other words, the new object points to the same memory locations as the original object. Any changes made to the original object will be reflected in the copied object, & vice versa. Shallow copying is the default behavior when assigning one object to another or when using the clone() method without any modification.
For example :
class ShallowCopy {
private int[] data;
public ShallowCopy(int[] values) {
data = values;
}
public void printData() {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
}
public class Main {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
ShallowCopy obj1 = new ShallowCopy(values);
ShallowCopy obj2 = obj1;
obj1.printData();
obj2.printData();
values[0] = 10;
obj1.printData();
obj2.printData();
}
}
Output:
1 2 3 4 5
1 2 3 4 5
10 2 3 4 5
10 2 3 4 5
In this example, `obj1` & `obj2` are shallow copies of each other. When we modify the `values` array, both `obj1` & `obj2` reflect the changes since they share the same reference to the array.
Deep Copy
Unlike shallow copying, deep copying creates a completely independent copy of the original object & all its associated objects. In a deep copy, the new object has its own set of references, & any changes made to the original object will not affect the copied object, & vice versa. Deep copying is useful when you want to create a true standalone copy of an object.
To achieve deep copying in Java, you need to manually create a new object & copy all the fields from the original object to the new object. If the object contains nested objects, you need to recursively create deep copies of those objects as well.
For example :
class DeepCopy {
private int[] data;
public DeepCopy(int[] values) {
data = new int[values.length];
for (int i = 0; i < values.length; i++) {
data[i] = values[i];
}
}
public void printData() {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
}
public class Main {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
DeepCopy obj1 = new DeepCopy(values);
DeepCopy obj2 = new DeepCopy(obj1.data);
obj1.printData();
obj2.printData();
values[0] = 10;
obj1.printData();
obj2.printData();
}
}
Output:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
In this example, `obj1` & `obj2` are deep copies of each other. The `DeepCopy` constructor creates a new array & copies the values from the original array to the new array. When we modify the `values` array, only `obj1` reflects the changes since it has its own independent copy of the data.