Fundamentals 7 min read

Understanding Shallow vs Deep Copy in Java ArrayList: Code Examples and Pitfalls

This article explains how Java's ArrayList.clone() creates a shallow copy that shares object references, demonstrates the resulting behavior with string and custom object lists, and shows how to implement a deep copy by manually cloning each element, complete with runnable code samples and console output.

FunTester
FunTester
FunTester
Understanding Shallow vs Deep Copy in Java ArrayList: Code Examples and Pitfalls

Introduction

The ArrayList class provides a clone() method that returns a shallow copy of the list, meaning only the references to the elements are duplicated. If an element's state changes in the original list, the change is reflected in the cloned list because both lists point to the same objects.

Shallow Copy Example (String List)

The following program creates a list of String objects, prints the original list, clones it with list.clone(), and prints the cloned list.

package com.fun;

import java.util.ArrayList;

public class AR {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("give");
        System.out.println("原始对象  : " + list);
        ArrayList clonedLis = (ArrayList) list.clone();
        System.out.println("拷贝对象  : " + clonedLis);
    }
}

Console output shows both lists contain the same strings, confirming a shallow copy.

Shallow Copy with Reference Objects

This example clones a list of custom Student objects, then modifies a field of the cloned object's element. Because the copy is shallow, the modification is visible in both the original and cloned lists.

package com.fun;

import java.util.ArrayList;

public class AR {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student(18, "fun"));
        list.add(new Student(20, "tester"));
        ArrayList<Student> clonedList = (ArrayList) list.clone();
        Student student = clonedList.get(1);
        student.name = "FunTester";
        System.out.println("原始对象  : " + clonedList);
        System.out.println("拷贝对象  : " + list);
    }
}

class Student {
    public int id;
    public String name;
    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        return "学生信息:id=" + id + ", name=" + name + "]";
    }
}

Console output demonstrates that both lists now show the name "FunTester" for the second student, illustrating that the shallow copy shares the same object instances.

Deep Copy Example

To avoid the reference‑sharing problem, the article implements a manual deep copy: it iterates over the original list, calls a custom clone() method on each Student, and adds the new independent objects to a new list.

package com.fun;

import com.fun.frame.httpclient.FanLibrary;
import java.util.ArrayList;

public class AR extends FanLibrary {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student(100, "fun"));
        list.add(new Student(101, "tester"));
        ArrayList<Student> clonedList = new ArrayList<>();
        for (Student student : list) {
            clonedList.add(student.clone());
        }
        Student student = clonedList.get(1);
        student.name = "FunTester";
        System.out.println("Cloned list : " + clonedList);
        System.out.println("Original list : " + list);
    }
}

class Student {
    public int id;
    public String name;
    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        return "学生信息:id=" + id + ", name=" + name + "]";
    }
    @Override
    public Student clone() {
        return new Student(this.id, this.name);
    }
}

Running this program prints a cloned list where the modified name "FunTester" appears only in the cloned list, while the original list still shows the original name "tester", confirming a successful deep copy.

Key Takeaways

Using ArrayList.clone() yields a shallow copy; object references are shared.

Modifying a referenced object after cloning affects both lists.

To achieve a deep copy, each element must be cloned individually, typically by implementing a clone() method or using a copy constructor.

References

The article cites two external WeChat posts that discuss JVM heap analysis of shallow vs deep copy and copying HttpRequestBase objects, providing additional context for readers who want to explore related topics.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaTutorialdeep copyArrayListshallow copyclone
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.