ArrayList不提供直接的深浅拷贝方法:浅拷贝(如new ArrayList()、addAll、stream.collect)仅复制引用,原列表与副本共享对象;深拷贝需手动克隆、序列化或构造新对象,确保元素独立。

ArrayList 本身不直接提供浅拷贝或深拷贝方法,但可以通过不同方式实现。关键区别在于:浅拷贝只复制引用(原列表和新列表共享同一组对象),深拷贝则为每个元素创建独立副本(互不影响)。
浅拷贝的几种常用方式
浅拷贝只需复制 ArrayList 的结构和元素引用,不涉及对象内部状态的复制。
-
构造方法复制:
new ArrayList(originalList)—— 最常用,底层调用Arrays.copyOf()复制引用数组 -
addAll() 方法:
List<T> copy = new ArrayList<>(); copy.addAll(originalList); -
Stream.collect()(Java 8+):
originalList.stream().collect(Collectors.toList())—— 同样是浅拷贝
注意:这些方式对 String、Integer 等不可变类型“看起来像深拷贝”,但本质仍是引用复制;对自定义可变对象(如 Person),修改副本中的对象会影响原列表。
深拷贝的核心思路
深拷贝必须确保每个元素对象本身也被复制,不能共用引用。没有通用一键方法,需根据对象特性选择策略。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
-
对象实现 Cloneable + 重写 clone():要求类中所有可变字段也支持克隆,并在
clone()中手动深拷贝嵌套对象 -
序列化反序列化(通用但有局限):将对象写入字节流再读出,可绕过引用。需确保所有元素及嵌套字段都实现
Serializable,且无transient关键数据丢失 -
使用第三方库(如 Apache Commons Lang):
SerializationUtils.clone(list)封装了序列化逻辑,简洁但仍有 Serializable 要求 - 手动构造新对象(最可控):遍历原列表,对每个元素调用其构造函数或工厂方法创建新实例,适合字段明确、逻辑清晰的场景
一个简单深拷贝示例(基于 clone)
假设有一个可深拷贝的 Person 类:
public class Person implements Cloneable {
private String name;
private Address address; // 假设 Address 也实现了 clone()
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) this.address.clone(); // 深拷贝嵌套对象
return cloned;
}
}
然后对 ArrayList 深拷贝:
List<Person> deepCopy = originalList.stream()
.map(p -> {
try { return (Person) p.clone(); }
catch (CloneNotSupportedException e) { throw new RuntimeException(e); }
})
.collect(Collectors.toList());
注意事项与常见误区
-
list.clone()返回的是Object,需强制转换;它本身是浅拷贝(JDK 源码证实),不要误以为是深拷贝 - 使用
Arrays.asList()创建的列表不支持add/remove,也不能用于需要扩容的拷贝场景 - 若元素含线程局部变量、数据库连接、文件句柄等资源,单纯 clone 或序列化无法正确复制,需特殊处理
- 性能上,深拷贝必然比浅拷贝开销大,尤其数据量大或对象图复杂时,应按需选择

















