Mark As Completed Discussion

Shallow Copy vs Deep Copy

If you know the basics of pointers, then you may have heard of the shallow copy and deep copy. All classes have a default copy constructor which is a shallow copy constructor.

Shallow Copy vs Deep Copy

Shallow copying is copying by reference (as opposed to copying by value). You will not notice any difference if your class has only primitive types (int, float, double, etc.). They will be copied by value in shallow copy as well. Suppose, however, you have an array as an attribute in the class. If you copy the object using the default copy constructor, then only the reference (or pointer) of the array will be copied. As a result, if you change a value at an index in the first object, then the value in the second object's array at that index will also be changed. See the code below for an example of a shallow copy.

TEXT/X-JAVA
1// Shallow Copy
2// MyClass.java
3public class MyClass {
4    protected int[] value;
5
6    // default constructor
7    public MyClass() {
8        value = {1,2,3,4,5}
9    }
10
11    // No Copy constructor, so the default will be used
12}
13
14// Main.java
15public class Main {
16    // Instantiating
17    MyClass myObj1 = new MyClass();
18    // Copying, will be using default constructor
19    MyClass myObj2 = new MyClass(myObj1);
20
21    myObj1.value[2] = 10;
22
23    // This will print: 1 2 10 4 5
24    for(int i=0; i<myObj1.value.length; i++) {
25        System.out.println(myObj1.value[i]);
26    }
27
28    // But this will also print: 1 2 10 4 5
29    for(int i=0; i<myObj2.value.length; i++) {
30        System.out.println(myObj2.value[i]);
31    }
32}

Now, to define a deep copy constructor, we need to create a separate array and then copy each element to the new array. See the code below:

TEXT/X-JAVA
1// Deep Copy
2// MyClass.java
3public class MyClass {
4    // For the sake of this example, we make it public to avoid excess getters
5    public int[] value;
6
7    // default constructor
8    public MyClass() {
9        value = {1,2,3,4,5};
10    }
11
12    // Copy constructor (Deep Copy)
13    public MyClass(MyClass other) {
14        this.value = new int[5];
15        for(int i = 0; i<5; i++) {
16            this.value[i] = other.value[i];
17        }
18    }
19}
20
21// Main.java
22public class Main {
23    // Instantiating
24    MyClass myObj1 = new MyClass();
25    // Copying, will be using default constructor
26    MyClass myObj2 = new MyClass(myObj1);
27
28    myObj1.value[2] = 10;
29
30    // This will print: 1 2 10 4 5
31    for(int i=0; i<myObj1.value.length; i++) {
32        System.out.println(myObj1.value[i]);
33    }
34
35    // This will now print unchanged: 1 2 3 4 5
36    for(int i=0; i<myObj2.value.length; i++) {
37        System.out.println(myObj2.value[i]);
38    }
39}