当前位置: 首页 > news >正文

深拷贝与浅拷贝的核心区别

深拷贝与浅拷贝的核心区别

浅拷贝​ 与 ​深拷贝​ 的核心差异在于 ​对象内部引用类型成员的处理方式​:

对比维度浅拷贝(Shallow Copy)​深拷贝(Deep Copy)​
复制深度仅复制对象本身,不复制引用成员指向的对象递归复制对象及其所有引用成员指向的对象
内存独立性拷贝对象与原对象共享引用成员拷贝对象与原对象完全独立
修改影响修改拷贝对象的引用成员会影响原对象修改拷贝对象的引用成员不会影响原对象
实现复杂度简单(自动复制引用地址)复杂(需手动处理嵌套引用)
适用场景引用成员不可变(如String)或无需独立性的场景引用成员可变且需要完全独立的场景

一、代码示例:浅拷贝与深拷贝实战

1. 定义需要拷贝的类结构
// 地址类(包含可变引用)
class Address implements Cloneable {String city;String street;Address(String city, String street) {this.city = city;this.street = street;}// 浅拷贝实现@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 仅复制Address的引用}
}// 用户类(包含引用类型成员)
class User implements Cloneable {String name;Address address;User(String name, Address address) {this.name = name;this.address = city;}// 浅拷贝实现@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 默认浅拷贝}// 深拷贝实现(手动处理嵌套对象)public User deepCopy() throws CloneNotSupportedException {User cloned = (User) super.clone();cloned.address = (Address) this.address.clone(); // 关键:递归复制引用对象return cloned;}
}
2. 测试两种拷贝的效果差异
public static void main(String[] args) throws Exception {// 原始对象Address addr = new Address("北京", "长安街");User original = new User("张三", addr);// 浅拷贝测试User shallowCopy = (User) original.clone();shallowCopy.address.street = "王府井"; // 修改拷贝对象的地址System.out.println(original.address.street);  // 输出:王府井(原对象被修改!)// 深拷贝测试User deepCopy = original.deepCopy();deepCopy.address.street = "中关村"; // 修改深拷贝后的地址System.out.println(original.address.street);  // 输出:王府井(原对象不受影响)
}

二、内存结构可视化对比

浅拷贝内存模型:
原始对象             拷贝对象
┌───────────┐       ┌───────────┐
│  User     │       │  User     │
│  name:张三├───────>│  name:张三│
│  address  │       │  address  │
└─────┬─────┘       └─────┬─────┘│                   │▼                   ▼┌─────────────┐│ Address     ││ city:北京   ││ street:王府井│└─────────────┘
深拷贝内存模型:
原始对象             深拷贝对象
┌───────────┐       ┌───────────┐
│  User     │       │  User     │
│  name:张三│       │  name:张三│
│  address  │       │  address  │
└─────┬─────┘       └─────┬─────┘│                   │▼                   ▼┌─────────────┐     ┌─────────────┐│ Address     │     │ Address     ││ city:北京   │     │ city:北京   ││ street:王府井│     │ street:中关村│└─────────────┘     └─────────────┘

三、深度剖析技术细节

1. ​不可变对象的特殊处理​:
  • 如果引用成员是不可变对象(如StringInteger),浅拷贝是安全的:
    User original = new User("李四", "上海"); // address改为String类型
    User copy = original.clone();
    copy.address = "广州"; // 新String对象创建,不影响原对象
2. ​多层深拷贝的实现​:
// 若Address中还包含其他引用类型
class Address {String city;Coordinate coord; // 新增坐标类@Overrideprotected Object clone() throws CloneNotSupportedException {Address cloned = (Address) super.clone();cloned.coord = (Coordinate) this.coord.clone(); // 递归深拷贝return cloned;}
}
3. ​替代深拷贝方案​:
  • 序列化反序列化​(无需实现Cloneable接口):
    public static <T> T deepCopy(T obj) throws IOException, ClassNotFoundException {ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(obj);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (T) ois.readObject();
    }
  • JSON序列化​(使用Gson/Jackson):
    Gson gson = new Gson();
    User copy = gson.fromJson(gson.toJson(original), User.class);

四、实际开发中的选型建议

场景推荐方案原因
简单对象(无嵌套引用)浅拷贝(默认clone方法)实现简单,性能高效
多层嵌套对象递归深拷贝或序列化方案确保所有层级对象独立
需要跨JVM传输对象序列化/反序列化天然支持对象图的完整复制
临时对象快速复制第三方工具(Apache Commons)避免手动实现深拷贝的复杂性

五、经典面试问题解析

问题1​:String类型成员在浅拷贝中是否安全?

  • 答案​:安全。因为String是不可变类,任何修改操作都会创建新对象,不会影响原对象。

问题2​:如何实现一个支持深拷贝的泛型工具方法?

  • 参考方案​:
    public static <T extends Serializable> T deepCopy(T obj) {try {ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(obj);ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (T) ois.readObject();} catch (Exception e) {throw new RuntimeException("Deep copy failed", e);}
    }

问题3​:深拷贝可能引发什么问题?

  • 潜在风险​:
    • 循环引用​:对象间相互引用导致无限递归
    • 性能损耗​:复制大型对象图时资源消耗高
    • 部分对象不可复制​:如数据库连接等资源型对象

通过以上多维度解析,可以系统掌握深拷贝与浅拷贝的核心差异及适用场景。

http://www.xdnf.cn/news/264907.html

相关文章:

  • 【unity游戏开发——Animator动画】Animation动画资源节约、优化、编辑修改小技巧
  • 人工智能:如何快速筛选出excel中某列存在跳号的单元格位置?
  • Manus联合创始人:公司产品基于Claude和阿里千问大模型开发
  • Java开发经验——ali编码规范经验总结
  • java面向对象编程【高级篇】之特殊类
  • 【Java多线程】计时器Timer/ScheduledExecutorService的使用
  • mysql主从复制搭建,并基于‌Keepalived + VIP实现高可用
  • MARM:推荐系统中的记忆增强突破
  • C++ - 数据容器之 forward_list(创建与初始化、元素访问、容量判断、元素遍历、添加元素、删除元素)
  • Python爬虫实战:获取企信网指定公司基本工商数据并分析,为客户选择公司做参考
  • 封装pinia并引入pinia持久化工具(pinia-plugin-persistedstate)
  • HarmonyOS NEXT——DevEco Studio的使用(还没写完)
  • 如何基于HAL库进行STM32开发
  • 华为云Flexus+DeepSeek征文|DeepSeek-V3商用服务开通教程
  • Python 学习
  • 4.29-4.30 Maven+单元测试
  • 【LeetCode Hot100】二分查找篇
  • Swift:重构开发范式的现代编程语言
  • 《高性能MySQL》第1讲:MySQL架构
  • 音视频开发技术总结报告
  • 对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础
  • 3.0/Q1,Charls最新文章解读
  • batch normalization和layer normalization区别
  • 循环缓冲区
  • QNAP Duplicati 备份 123云盘
  • Java接口全面教程:从入门到精通
  • ai之paddleOCR 识别PDF python312和paddle版本冲突 GLIBCXX_3.4.30
  • C与指针4——指针
  • 每天一道面试题@第五天
  • 第九课认识倍数