ArrayList不提供深度复制,其clone()和构造函数仅浅拷贝;深度复制需元素自身支持或手动遍历调用deepCopy(),不可变类型无需深拷贝,序列化等方案各有局限。

ArrayList 本身不提供深度复制功能,它的 clone() 和构造函数(如 new ArrayList(original))都只做浅拷贝——即复制了列表结构和引用,但不复制元素对象本身。要实现深度复制,关键在于:你得让每个元素自己完成深拷贝,ArrayList 只负责组织和复制这些已深拷贝后的对象。
确认元素类型是否支持深拷贝
只有当 ArrayList 中的元素是可变对象(如自定义类、HashMap、嵌套 List 等),且你希望副本修改不影响原对象时,才需要深拷贝。如果元素是不可变类型(如 String、Integer),浅拷贝就等价于深拷贝,无需额外操作。
常见做法:
- 元素类实现
Cloneable并重写clone(),确保递归复制所有可变字段 - 提供一个带参构造函数或静态工厂方法(如
copy()),显式创建新实例并复制内部状态 - 使用序列化(如
ObjectOutputStream+ByteArrayInputStream)——适用于所有可序列化的类,但性能低、有局限(如含 transient 或不可序列化字段会失败)
手动遍历 + 元素级复制(推荐)
这是最清晰、可控性最强的方式。假设你有一个 Person 类,并已提供 deepCopy() 方法:
立即学习“Java免费学习笔记(深入)”;
ArrayList<Person> original = new ArrayList<>(Arrays.asList(p1, p2, p3));
ArrayList<Person> deepCopy = new ArrayList<>();
for (Person p : original) {
deepCopy.add(p.deepCopy()); // 调用每个对象自己的深拷贝逻辑
}
或者用 Stream 简写:
ArrayList<Person> deepCopy = original.stream()
.map(Person::deepCopy)
.collect(Collectors.toCollection(ArrayList::new));
使用第三方库简化(如 Apache Commons Lang)
如果项目已引入 commons-lang3,且元素类实现了 Serializable,可用 SerializationUtils.clone():
import org.apache.commons.lang3.SerializationUtils; ArrayList<Person> deepCopy = SerializationUtils.clone(original);
注意:Person 及其所有字段类型(包括嵌套对象)都必须实现 Serializable,否则抛异常;静态字段、transient 字段不会被复制。
避免踩坑的几个细节
深度复制不是“调一个方法就完事”,容易忽略的点:
- 循环引用:若对象图中存在 A→B→A,直接序列化或递归 clone 会栈溢出,需用缓存机制(如
IdentityHashMap)记录已拷贝对象 - 资源型对象(如
FileInputStream、数据库连接)无法也不应深拷贝,需明确设计为不可复制或重新初始化 - Builder 模式或不可变对象优先:如果
Person是不可变类(所有字段 final + 无 setter),那根本不需要深拷贝,直接共享安全
深度复制的本质是对象图的重建,ArrayList 只是容器。真正的工作在元素自身——要么它自己能复制自己,要么你帮它复制。没有银弹,按需选择最可控的方式即可。


















