java--浅拷贝&深拷贝
Java对象拷贝分为浅拷贝和深拷贝。浅拷贝仅复制基本类型值和引用地址,副本与原对象共享引用对象;深拷贝则会完全复制引用对象,实现完全独立。浅拷贝通过实现Cloneable接口重写clone()方法实现,深拷贝可通过手动clone引用对象、序列化或工具库实现。深拷贝性能较低但能确保对象独立性,适合复杂引用场景,而浅拷贝适用于简单对象复制。开发中应根据需求选择拷贝方式,通常推荐使用深拷贝以避免引用共享
1. 什么是拷贝?
在 Java 中,拷贝对象的过程可以分为两类:
浅拷贝(Shallow Copy)
仅复制对象本身的基本类型属性和引用类型的地址,不会复制引用对象本身。深拷贝(Deep Copy)
不仅复制对象本身,还会复制其引用类型所指向的对象,即完全复制一个“独立”的副本。
2. 浅拷贝(Shallow Copy)
📌 特点
基本数据类型 → 值被复制。
引用数据类型(对象、数组)→ 只复制引用地址,拷贝后的对象和原对象指向同一块内存。
修改引用对象的内容时,两个对象会同时变化。
📌 实现方式
实现
Cloneable接口并重写clone()方法(默认就是浅拷贝)。使用构造方法赋值(只复制属性,不做深层次复制)。
📌 示例
class Address { String city; Address(String city) { this.city = city; } } class Person implements Cloneable { String name; int age; Address address; Person(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); // 默认浅拷贝 } } public class ShallowCopyDemo { public static void main(String[] args) throws Exception { Address addr = new Address("Beijing"); Person p1 = new Person("Tom", 20, addr); Person p2 = (Person) p1.clone(); System.out.println(p1.address.city); // Beijing System.out.println(p2.address.city); // Beijing p2.address.city = "Shanghai"; System.out.println(p1.address.city); // Shanghai(浅拷贝影响了原对象) } }
3. 深拷贝(Deep Copy)
📌 特点
基本数据类型 → 值被复制。
引用数据类型 → 会复制引用对象本身,两个对象完全独立。
修改副本对象不会影响原始对象。
📌 实现方式
手动实现深拷贝
在clone()中,除了调用super.clone(),还对引用对象进行手动clone。序列化与反序列化
把对象写到流中,再读出来,就会得到一份新的对象,属于完全深拷贝。使用第三方工具库(如 Apache Commons Lang 的
SerializationUtils.clone())。
📌 示例1:手动深拷贝
class Address implements Cloneable { String city; Address(String city) { this.city = city; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable { String name; int age; Address address; Person(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } @Override protected Object clone() throws CloneNotSupportedException { Person cloned = (Person) super.clone(); cloned.address = (Address) address.clone(); // 手动克隆引用对象 return cloned; } } public class DeepCopyDemo1 { public static void main(String[] args) throws Exception { Address addr = new Address("Beijing"); Person p1 = new Person("Tom", 20, addr); Person p2 = (Person) p1.clone(); p2.address.city = "Shanghai"; System.out.println(p1.address.city); // Beijing(深拷贝互不影响) System.out.println(p2.address.city); // Shanghai } }
📌 示例2:序列化深拷贝
import java.io.*; class Address implements Serializable { String city; Address(String city) { this.city = city; } } class Person implements Serializable { String name; int age; Address address; Person(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } } public class DeepCopyDemo2 { public static void main(String[] args) throws Exception { Address addr = new Address("Beijing"); Person p1 = new Person("Tom", 20, addr); // 序列化 → 字节数组 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(p1); // 反序列化 → 新对象 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); Person p2 = (Person) ois.readObject(); p2.address.city = "Shanghai"; System.out.println(p1.address.city); // Beijing System.out.println(p2.address.city); // Shanghai } }
4. 浅拷贝 vs 深拷贝 对比表
特性 浅拷贝 深拷贝 基本类型 拷贝值 拷贝值 引用类型 拷贝引用地址 拷贝新对象 是否独立 否,共享引用对象 是,完全独立 实现方式 Object.clone()默认手动 clone / 序列化 / 工具库 性能 较快 较慢(需要额外复制引用对象) 使用场景 只需要复制对象本身,不关心引用对象 必须保证副本和原对象互不影响
5. 总结
浅拷贝:复制对象时,引用对象仍然共享,修改会互相影响。
深拷贝:复制对象时,引用对象也会被复制,完全独立。
实现方式:
浅拷贝:
clone()默认实现深拷贝:手动
clone()引用对象 / 序列化反序列化 / 工具类👉 一般情况下,如果对象中包含复杂的引用关系(如数组、集合、对象嵌套),推荐使用 深拷贝。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)