大厂面试中,“浅拷贝”是一个高频考点,它不仅是理解对象复制的基石,也是深入内存管理的关键。
浅拷贝是什么
浅拷贝(shallow copy)是一种对象复制方式。其核心在于:仅复制对象本身的顶层属性或引用,而不会递归地复制其内部引用的可变对象。

图1:浅拷贝示意图,展示了克隆对象与原型对象共享引用类型成员
具体来说:
- 对于基本数据类型(如数字、字符串、布尔值)的字段,浅拷贝会创建独立的副本。
- 但对于引用类型的字段(如数组、字典、对象、列表等),浅拷贝仅仅复制了指向堆内存中那个子对象的地址(引用)。这意味着,源对象和拷贝后的新对象共享了同一个子对象。
浅拷贝有什么价值
为什么我们需要浅拷贝?它主要应用于那些需要高效复制对象结构,但又不必要求深层数据完全独立的场景:
- 性能与内存优化:复制成本低,避免了深度遍历和创建大量新对象的开销,适用于大型对象或需要频繁复制的场景。
- 保持结构一致性:当多个对象可以安全地共享某些不可变或无需独立管理的子对象时,浅拷贝是理想选择。
- 安全的顶层数据修改:你可以在不改变原对象顶层引用的情况下,对拷贝对象的顶层字段进行独立的修改。
浅拷贝实现原理
浅拷贝的本质是对内存地址的复制。为了理解这一点,我们需要先了解计算机内存中“栈”和“堆”的存储模型:
- 基本类型的值直接存放在栈内存中。
- 引用类型的实际数据存放在堆内存中,而在栈内存中只存放一个指向堆内存中该数据的地址(指针)。
以 Java 为例,通过实现 Cloneable 接口并调用 Object.clone() 方法,得到的就是一个典型的浅拷贝:
class User implements Cloneable {
String name; // String 具有不变性,此处可视为值
Address address; // 引用类型
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 默认的clone()方法实现的就是浅拷贝
}
}
当你执行一次浅拷贝时,背后发生了什么?
- 程序会在栈内存中开辟一块新空间,用于存放新对象。
- 然后遍历原对象的所有字段,将其值依次复制到新对象的对应字段中。
- 当遇到引用类型字段(一个指针)时,它不会去堆里复制一份完整的数据,而是直接复制这个指针的地址值。
因此,新对象中的引用类型字段和原对象中的对应字段,指向的是堆内存中的同一个地址,这就是它们共享子对象的根本原因。如果你想深入学习更多关于 JVM 内存管理的知识,可以查阅相关资料。
理解浅拷贝是掌握 Java 对象模型和 计算机基础 中内存管理概念的重要一环。更多深入的技术讨论和实践分享,欢迎在云栈社区与广大开发者交流。
|