Java 浅拷贝与深拷贝原理、实现与代码示例全解析在 Java 中对象拷贝是开发中常见的需求复制对象以避免对原对象的修改在缓存、数据传输、并发场景中保持对象独立理解浅拷贝Shallow Copy和深拷贝Deep Copy的区别对于写出安全、高效的 Java 程序非常重要也是面试常问知识点。本文将系统讲解浅拷贝与深拷贝的概念Java 实现方式多种代码示例常见误区与面试高频点一、浅拷贝Shallow Copy1.1 概念浅拷贝只复制对象本身而不复制对象内部引用的其他对象。原对象和拷贝对象共享内部引用对象。可理解为对象A -- 引用对象X 拷贝对象B -- 同样引用对象X修改引用对象会影响原对象和拷贝对象。1.2 浅拷贝示例假设有一个Person类classPersonimplementsCloneable{Stringname;intage;Addressaddress;// 引用类型publicPerson(Stringname,intage,Addressaddress){this.namename;this.ageage;this.addressaddress;}OverrideprotectedObjectclone()throwsCloneNotSupportedException{returnsuper.clone();// 默认浅拷贝}OverridepublicStringtoString(){returnname, age, address;}}classAddress{Stringcity;publicAddress(Stringcity){this.citycity;}OverridepublicStringtoString(){returncity;}}测试浅拷贝publicclassTestShallow{publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{AddressaddrnewAddress(Beijing);Personp1newPerson(Alice,30,addr);Personp2(Person)p1.clone();System.out.println(p1: p1);System.out.println(p2: p2);// 修改地址p2.address.cityShanghai;System.out.println(修改后 p1: p1);System.out.println(修改后 p2: p2);}}输出结果p1: Alice, 30, Beijing p2: Alice, 30, Beijing 修改后 p1: Alice, 30, Shanghai 修改后 p2: Alice, 30, Shanghai可以看到p1和p2的address是同一个对象浅拷贝不会复制引用对象二、深拷贝Deep Copy2.1 概念深拷贝会复制对象本身以及其内部引用的所有对象原对象和拷贝对象互不影响可理解为对象A -- 引用对象X 拷贝对象B -- 新的引用对象X独立修改引用对象不会影响原对象。2.2 深拷贝实现方式1. 通过clone()方法实现深拷贝在clone()方法中手动复制引用对象classPersonimplementsCloneable{Stringname;intage;Addressaddress;publicPerson(Stringname,intage,Addressaddress){this.namename;this.ageage;this.addressaddress;}OverrideprotectedObjectclone()throwsCloneNotSupportedException{Personcloned(Person)super.clone();cloned.addressnewAddress(this.address.city);// 复制引用对象returncloned;}OverridepublicStringtoString(){returnname, age, address;}}测试深拷贝publicclassTestDeep{publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{AddressaddrnewAddress(Beijing);Personp1newPerson(Alice,30,addr);Personp2(Person)p1.clone();p2.address.cityShanghai;System.out.println(p1: p1);System.out.println(p2: p2);}}输出p1: Alice, 30, Beijing p2: Alice, 30, Shanghai✅ 修改p2.address不影响p1.address2. 通过序列化实现深拷贝利用对象序列化将对象写入字节流再读出importjava.io.*;classPersonimplementsSerializable{Stringname;intage;Addressaddress;publicPerson(Stringname,intage,Addressaddress){this.namename;this.ageage;this.addressaddress;}}classAddressimplementsSerializable{Stringcity;publicAddress(Stringcity){this.citycity;}}publicclassDeepCopyBySerialization{publicstaticvoidmain(String[]args)throwsException{AddressaddrnewAddress(Beijing);Personp1newPerson(Alice,30,addr);// 序列化 - 反序列化ByteArrayOutputStreambosnewByteArrayOutputStream();ObjectOutputStreamoosnewObjectOutputStream(bos);oos.writeObject(p1);ByteArrayInputStreambisnewByteArrayInputStream(bos.toByteArray());ObjectInputStreamoisnewObjectInputStream(bis);Personp2(Person)ois.readObject();p2.address.cityShanghai;System.out.println(p1: p1.address.city);// BeijingSystem.out.println(p2: p2.address.city);// Shanghai}}优点简单、通用可复制复杂对象包含多层引用缺点性能相对慢需要对象实现Serializable接口三、浅拷贝与深拷贝总结类型拷贝内容是否复制引用对象修改引用对象影响原对象实现方式浅拷贝对象本身否会影响Object.clone()默认深拷贝对象及引用对象是不影响手动clone()/ 序列化四、面试高频点1.浅拷贝 vs 深拷贝浅拷贝只复制对象不复制对象引用深拷贝复制对象及其所有引用对象2.Cloneable 接口必须实现才能使用Object.clone()默认clone()是浅拷贝3.序列化深拷贝对象及其引用对象都必须实现Serializable用于复杂对象深拷贝4.修改对象引用的影响浅拷贝修改内部引用会影响原对象深拷贝不会5.集合中的拷贝List、Map、Set 等也涉及浅拷贝与深拷贝复制集合对象时要注意元素引用是否共享示例ListPersonlist1newArrayList();list1.add(newPerson(Alice,30,newAddress(Beijing)));// 浅拷贝集合ListPersonlist2newArrayList(list1);list2.get(0).address.cityShanghai;System.out.println(list1.get(0).address.city);// Shanghai五、总结浅拷贝只复制对象本身引用对象共享深拷贝复制对象及引用对象互不影响实现方式浅拷贝Object.clone()深拷贝手动 clone / 序列化面试重点对象引用的理解Cloneable接口与clone()方法修改内部引用的副作用集合对象的浅拷贝问题