Understanding Reference, Shallow, and Deep Copy in Java
This article explains Java reference copying, object cloning, and the differences between shallow and deep copy, providing code examples and output analysis to illustrate how each method affects object identity and shared references.
1. Reference Copy
Reference copy creates a new variable that points to the same object; both variables share the same memory address.
Teacher teacher = new Teacher("Taylor", 26);
Teacher otherteacher = teacher;
System.out.println(teacher);
System.out.println(otherteacher);Output shows identical hash codes, confirming they reference the same object.
2. Object Copy (Clone)
Object copy creates a distinct object instance, typically via the clone() method.
Teacher teacher = new Teacher("Swift", 26);
Teacher otherteacher = (Teacher) teacher.clone();
System.out.println(teacher);
System.out.println(otherteacher);Output shows different hash codes, indicating a new object was created.
3. Shallow Copy
Shallow copy duplicates the fields of an object but does not recursively copy objects referenced by those fields; referenced objects remain shared.
package com.test;
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("riemann");
teacher.setAge(27);
Student2 student1 = new Student2();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher);
Student2 student2 = (Student2) student1.clone();
System.out.println("After copy");
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
System.out.println("After modifying teacher");
// modify teacher's name
teacher.setName("Games");
System.out.println(student1.getTeacher().getName());
System.out.println(student2.getTeacher().getName());
}
}
class Teacher implements Cloneable {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
class Student2 implements Cloneable {
private String name;
private int age;
private Teacher teacher;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Teacher getTeacher() { return teacher; }
public void setTeacher(Teacher teacher) { this.teacher = teacher; }
public Object clone() throws CloneNotSupportedException { return super.clone(); }
}Both student1 and student2 are separate Student2 instances, but their teacher fields reference the same Teacher object; after changing the teacher’s name, both students reflect the change, demonstrating shallow copy behavior.
4. Deep Copy
Deep copy creates a completely independent copy of an object and all objects it references, usually by cloning nested objects manually.
package com.test;
public class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher2 teacher = new Teacher2();
teacher.setName("riemann");
teacher.setAge(27);
Student3 student1 = new Student3();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher);
Student3 student2 = (Student3) student1.clone();
System.out.println("After copy");
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getTeacher().getName());
System.out.println(student2.getTeacher().getAge());
System.out.println("After modifying teacher");
// modify teacher's name
teacher.setName("Games");
System.out.println(student1.getTeacher().getName());
System.out.println(student2.getTeacher().getName());
}
}
class Teacher2 implements Cloneable {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Object clone() throws CloneNotSupportedException { return super.clone(); }
}
class Student3 implements Cloneable {
private String name;
private int age;
private Teacher2 teacher;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Teacher2 getTeacher() { return teacher; }
public void setTeacher(Teacher2 teacher) { this.teacher = teacher; }
public Object clone() throws CloneNotSupportedException {
// shallow clone first
Student3 copy = (Student3) super.clone();
// then deep clone the teacher
copy.setTeacher((Teacher2) this.teacher.clone());
return copy;
}
}After cloning, the teacher inside student2 is a separate copy; modifying the original teacher’s name does not affect student2 ’s teacher, confirming deep copy behavior.
This guide demonstrates how reference copy, shallow copy, and deep copy differ in Java, helping developers choose the appropriate cloning strategy for their applications.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.