Table of contents
1.
Introduction
2.
Methods of Copying
2.1.
Shallow Copy
2.2.
Deep Copy
3.
Cloning
4.
Frequently Asked Questions
4.1.
What is the difference between shallow copying & deep copying?
4.2.
When should I use shallow copying vs deep copying?
4.3.
Can I use the clone() method for deep copying?
5.
Conclusion
Last Updated: Nov 5, 2024

Deep Cloning and Shallow Cloning in Java

Author Rahul Singh
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

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. 

Deep Cloning and Shallow Cloning in Java

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(); 
    }
}
You can also try this code with Online Java Compiler
Run Code


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(); 
    }
}
You can also try this code with Online Java Compiler
Run Code


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.

Cloning

Cloning is another way to create a copy of an object in Java. It is a built-in mechanism that allows you to create a new object with the same state as the original object. To use cloning, the class must implement the `Cloneable` interface & override the `clone()` method.

For example : 

class Cloning implements Cloneable {
    private int[] data;

    public Cloning(int[] values) {
        data = values;
    }

    public void printData() {
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    @Override
    public Cloning clone() throws CloneNotSupportedException {
        Cloning cloned = (Cloning) super.clone();
        cloned.data = data.clone();
        return cloned;
    }
}
public class Main {
    public static void main(String[] args) {
        int[] values = {1, 2, 3, 4, 5};
        Cloning obj1 = new Cloning(values);

        try {
            Cloning obj2 = obj1.clone();

            obj1.printData(); 
            obj2.printData(); 

            values[0] = 10;

            obj1.printData(); 
            obj2.printData(); 
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output: 

1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5


In this example, the `Cloning` class implements the `Cloneable` interface & overrides the `clone()` method. Inside the `clone()` method, we first call `super.clone()` to create a shallow copy of the object. Then, we manually create a deep copy of the `data` array using `data.clone()`.

Note: When we invoke `obj1.clone()`, it creates a new object `obj2` with the same state as `obj1`. Any changes made to the original object or its associated objects will not affect the cloned object.

Frequently Asked Questions

What is the difference between 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.

When should I use shallow copying vs deep copying?

Shallow copying is useful when you want to create a new object that refers to the same underlying data as the original object. Deep copying is necessary when you want to create a true standalone copy of an object that is entirely independent of the original.

Can I use the clone() method for deep copying?

By default, the clone() method performs a shallow copy. However, you can override the clone() method to create a deep copy by manually copying the object's fields & recursively cloning any nested objects.

Conclusion

In this article, we discussed the concepts of shallow copying, deep copying, & cloning in Java. We learned that shallow copying creates a new object with shared references, while deep copying creates a completely independent copy. We also explained how to use the clone() method to create copies of objects. 

You can also check out our other blogs on Code360.

Live masterclass