system.arraycopy只能实现对象数组的浅拷贝,因为它仅复制引用地址而非对象内容;修改新数组对象属性会影响原数组,替换引用则不影响;深拷贝需逐个克隆、序列化或手动创建新对象。

System.arraycopy 不能实现对象数组的深拷贝,它只做浅拷贝 —— 即复制数组引用本身,而非引用指向的对象内容。
为什么 arraycopy 是浅拷贝
System.arraycopy 本质是内存块复制,对对象数组而言,它把原数组中每个元素(即对象的引用地址)逐个复制到新数组中。新旧数组中的元素仍指向堆内存中同一组对象。
- 修改新数组中某个对象的属性,原数组对应对象也会变化
- 替换新数组中某个索引的引用(如赋值为 new Object()),不影响原数组
- 这和 clone() 方法对数组的行为一致,都只复制一层
真正需要深拷贝时怎么办
要实现对象数组深拷贝,必须逐个创建原对象的副本。具体方式取决于对象是否支持克隆或序列化:
- 若对象实现了 Cloneable 接口且重写了 clone(),可遍历调用:newArray[i] = (T) original[i].clone()
- 若对象可序列化(implements Serializable),可用 ObjectOutputStream/ObjectInputStream 实现通用深拷贝(注意性能开销)
- 手动构造新对象(如 new Person(p.getName(), p.getAge())),适用于结构简单、可控的场景
- 使用第三方库(如 Apache Commons Lang 的 SerializationUtils.clone 或 Gson 序列化/反序列化)
常见误区提醒
有人误以为“复制了整个数组”就等于“复制了所有对象”,其实只是复制了 N 个指针。调试时可通过打印对象的 hashCode() 验证:深拷贝前后同位置对象的 hashCode 应不同;浅拷贝则相同。
- String 数组用 arraycopy 看似“安全”,是因为 String 不可变,但本质仍是浅拷贝
- 基本类型数组(int[]、boolean[] 等)不存在深浅之分,arraycopy 完全满足需求
- Arrays.copyOf 底层也调用 arraycopy,行为完全一致
一个简单可靠的深拷贝示例(基于 clone)
假设 Person 类正确实现了 clone:
Person[] original = {new Person("Alice", 25), new Person("Bob", 30)};
Person[] deepCopy = new Person[original.length];
for (int i = 0; i
此时修改 deepCopy[0].setName("Alicia"),不会影响 original[0]。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











