java数组深拷贝需区分元素类型:基本类型数组用clone()或system.arraycopy即为深拷贝;对象数组仅clone()是浅拷贝,必须递归克隆每个元素或使用拷贝构造器。

Java 数组深拷贝不是“调用 clone 就完事”,关键看元素类型。基本类型数组用 clone() 或 System.arraycopy 就是深拷贝;但对象数组(比如 String[]、User[])只调用 clone() 只是浅拷贝——新数组里每个元素仍是原对象的引用,改一个,两边都变。
一、一维数组的深拷贝:基础但易踩坑
对 int[]、double[] 这类基本类型数组,以下三种方式本质等效,都是真正的深拷贝:
-
直接调用
clone():简洁安全,JVM 内部优化,无需手动分配目标数组 System.arraycopy(src, 0, dest, 0, length)
Arrays.copyOf(src, src.length)
但注意:clone() 和 <code>arraycopy 对 Object[] 只复制引用,不是递归克隆对象本身。例如:
String[] a = {"hello", "world"};
String[] b = a.clone(); // ✅ 元素是不可变 String,效果等同深拷贝
b[0] = "hi"; // ✅ 不影响 a
User[] users = {new User("Alice"), new User("Bob")};
User[] copies = users.clone(); // ❌ 只复制了两个 User 引用
copies[0].setName("Carol"); // ⚠️ a[0] 的 name 也会变成 Carol
二、对象数组真正深拷贝:必须递归处理每个元素
要让 User[] 类型数组实现真正隔离,得逐个调用元素的 clone() 或构造新实例:
- 确保
User实现Cloneable并重写clone()方法,返回新对象 - 拷贝时循环创建新数组,并对每个元素显式克隆:
cloned[i] = users[i].clone() - 更推荐方式:提供拷贝构造器或静态工厂方法,避免
clone()的脆弱性(如 final 字段、异常处理、继承链问题)
示例写法:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
public static User[] deepCopy(User[] src) {
if (src == null) return null;
User[] dst = new User[src.length];
for (int i = 0; i
<h3>三、集合类(如 ArrayList)的深拷贝不能靠 .clone()</h3>
<p><code>ArrayList.clone()</code> 是典型浅拷贝:它新建了一个 <code>ArrayList</code> 容器,但里面存的还是原对象的引用。即使元素是 <code>String</code> 没问题(因不可变),一旦含可变对象(如 <code>User</code>、<code>HashMap</code>),就会互相污染。</p>
- 错误示范:
ArrayList<user> copy = (ArrayList<user>) original.clone();</user></user> - 正确做法:遍历 + 深拷贝每个元素,再 add 到新列表
- 通用方案:用序列化反序列化(
SerializationUtils.clone()),前提是所有嵌套类型都实现Serializable - 替代思路:若结构简单且无自定义类,可用
new ArrayList(original)——但这仍是浅拷贝,仅适用于元素不可变或你明确接受共享引用
四、多维数组深拷贝:每一层都要手动处理
int[][] 用 clone() 或 arraycopy 只复制了外层数组引用,内层数组仍共享。例如:
int[][] mat = {{1,2}, {3,4}};
int[][] copy = mat.clone(); // 外层数组独立,但 copy[0] == mat[0]
copy[0][0] = 99; // ⚠️ mat[0][0] 也变成 99
真正深拷贝需两层循环:
- 先创建新外层数组:
int[][] deep = new int[mat.length][]; - 再对每行单独拷贝:
deep[i] = mat[i].clone();(对int[]行有效) - 若为
User[][],则需三层逻辑:外层循环 → 创建新行 → 内层循环克隆每个User
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










