Shallow Copy
May 20, 2023
A shallow copy is a type of object copy in which a new object is created with the same values as an existing object, but with references to the same objects for any reference type fields. In other words, a shallow copy creates a new object that has the same values as the original object, but it does not create new copies of the objects referenced by the original object. Instead, it refers to the same objects as the original.
Purpose
The purpose of creating shallow copies is to reduce the amount of memory required to store objects. When objects are copied, their values need to be stored in memory, and any reference type fields must also be copied. This can be very time-consuming and memory-intensive, especially for large objects with many fields. By creating a shallow copy instead, only the values of the object are stored in memory, while the reference type fields are simply pointed to the same objects as the original, reducing the amount of memory required.
Usage
Shallow copies are commonly used in programming languages that support object-oriented programming, such as Java, Python, and C#. In Java, for example, the clone()
method can be used to create a shallow copy of an object. The Object.clone()
method creates a new object that is a copy of the original object, but with references to the same objects as the original.
public class MyClass implements Cloneable {
public int value;
public MyObject obj;
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
In this example, the MyClass
object has a field obj
of type MyObject
. When a shallow copy of MyClass
is created, the new object will have a reference to the same MyObject
as the original.
MyClass obj1 = new MyClass();
obj1.value = 10;
obj1.obj = new MyObject();
MyClass obj2 = (MyClass) obj1.clone();
obj2.value = 20;
obj2.obj.setValue(30);
System.out.println(obj1.value); // Output: 10
System.out.println(obj2.value); // Output: 20
System.out.println(obj1.obj.getValue()); // Output: 30
System.out.println(obj2.obj.getValue()); // Output: 30
In this example, obj1
is an instance of MyClass
with a value of 10 and a MyObject
field with a value of 0. obj2
is a shallow copy of obj1
, so it has the same value of 10 and references the same MyObject
. When the value of obj2.value
is changed to 20, it does not affect the value of obj1.value
because they are separate objects. However, when the value of obj2.obj
is changed to 30, it affects the value of obj1.obj
as well because they reference the same object.
Shallow copies can also be used to create copies of collections, such as arrays and lists, that contain reference types. In Java, for example, the Arrays.copyOf()
method can be used to create a shallow copy of an array. This method creates a new array with the same length as the original and copies the values of the original array into the new array. However, any reference type elements in the array are simply pointed to the same objects as the original array.
MyObject[] array1 = new MyObject[3];
array1[0] = new MyObject();
array1[1] = new MyObject();
array1[2] = new MyObject();
MyObject[] array2 = Arrays.copyOf(array1, array1.length);
array2[0].setValue(10);
System.out.println(array1[0].getValue()); // Output: 10
System.out.println(array2[0].getValue()); // Output: 10
In this example, array1
is an array of MyObject
with a length of 3, and array2
is a shallow copy of array1
. When the value of array2[0]
is changed to 10, it affects the value of array1[0]
as well because they reference the same MyObject
.
Comparison with Deep Copy
A shallow copy is often compared with a deep copy, which creates a new object with new copies of all the objects referenced by the original object. In other words, a deep copy creates a new object that is completely independent of the original object, whereas a shallow copy creates a new object that shares some objects with the original object.
public class MyClass implements Cloneable {
public int value;
public MyObject obj;
public Object clone() {
try {
MyClass copy = (MyClass) super.clone();
copy.obj = (MyObject) obj.clone();
return copy;
} catch (CloneNotSupportedException e) {
return null;
}
}
}
In this example, the clone()
method creates a shallow copy of the MyClass
object using the super.clone()
method, and then creates a deep copy of the MyObject
field using the obj.clone()
method. This creates a new MyObject
object that is independent of the original MyObject
.
MyClass obj1 = new MyClass();
obj1.value = 10;
obj1.obj = new MyObject();
MyClass obj2 = (MyClass) obj1.clone();
obj2.value = 20;
obj2.obj.setValue(30);
System.out.println(obj1.value); // Output: 10
System.out.println(obj2.value); // Output: 20
System.out.println(obj1.obj.getValue()); // Output: 0
System.out.println(obj2.obj.getValue()); // Output: 30
In this example, obj1
is an instance of MyClass
with a value of 10 and a MyObject
field with a value of 0. obj2
is a deep copy of obj1
, so it has a new MyObject
with a value of 0. When the value of obj2.value
is changed to 20, it does not affect the value of obj1.value
because they are separate objects. When the value of obj2.obj
is changed to 30, it does not affect the value of obj1.obj
because they reference different objects.