java数组克隆需区分容器复制与内容复制:基本类型天然隔离,对象数组分浅拷贝(arrays.copyof等仅复制引用)和深拷贝(需类实现cloneable并递归克隆引用字段)。

Java数组克隆不是简单复制引用,而是要明确区分“复制数组容器”和“复制里面的内容”。基本类型数组拷贝后天然隔离;对象数组则必须判断:你是只需要新数组装着原对象(浅拷贝),还是连每个对象都要全新一份(深拷贝)。
对象数组的浅拷贝:快但共享对象
Arrays.copyOf()、clone()、System.arraycopy() 都属于浅拷贝。它们在堆中新开一块内存放数组本身,但数组里的每个元素——比如 Person 实例——仍是原对象的引用。
- 适用场景:数组元素是不可变对象(String、Integer、LocalDate)或业务中从不修改对象内部状态
- 验证方法:改 copy[0].name 后,original[0].name 也变了 → 就是浅拷贝生效了
- 常见误用:以为 arr2 = arr1.clone() 就安全了,其实只是数组地址不同,里面 Person 还是同一个
手动 clone 实现深拷贝:可控且高效
前提是你的类已正确定义 clone(),且对所有可变引用字段递归调用 clone()。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- Person 类需实现 Cloneable,并重写 public Person clone(),内部对 address、hobbies 等引用字段显式克隆
- 数组层面只需遍历:Person[] copy = new Person[src.length]; for (int i = 0; i
- 优点是零序列化开销、类型安全、性能好;缺点是每个被引用的类都得支持正确 clone
JSON 序列化反序列化:简单 DTO 场景首选
适合结构扁平、无函数、无 Date/Map/Set 循环引用的 POJO 数组。
- 一行转 JSON,一行还原:Gson gson = new Gson(); String json = gson.toJson(src); Person[] copy = gson.fromJson(json, Person[].class);
- 自动跳过方法、transient 字段;Date 变字符串;不支持循环引用
- 常用于前后端传输后重建、单元测试构造干净数据,不适合含复杂状态的业务对象
序列化/反序列化:通用但有代价
唯一能处理任意嵌套、含集合、自定义类甚至循环引用(配合 @Transient 或 Externalizable)的方案。
- 要求所有类及字段类型都实现 Serializable;transient 字段默认不复制,需额外逻辑补全
- 封装成工具方法时,必须捕获 IOException 和 ClassNotFoundException
- 性能低于手动 clone,且反序列化不受信数据存在安全风险(如恶意字节流触发远程代码执行)
深拷贝的本质不在数组操作,而在每个对象是否真正独立。选哪种方式,取决于你对象的结构复杂度、性能要求和维护成本。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










