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

Java对象克隆:从浅到深的奥秘

浅克隆与深克隆在Java中的应用及区别

核心概念
  1. 浅克隆
    复制对象时仅克隆基本数据类型字段,引用类型字段共享原对象引用。实现方式:
class Person implements Cloneable {String name;Address address; // 引用类型字段@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 默认浅克隆}
}class Address {String city;
}

     2.深克隆
        完全独立复制对象及其关联对象:

class DeepPerson implements Cloneable {String name;Address address;@Overrideprotected Object clone() throws CloneNotSupportedException {DeepPerson cloned = (DeepPerson) super.clone();cloned.address = new Address(); // 新建独立地址对象cloned.address.city = this.address.city;return cloned;}
}

应用场景对比
特性浅克隆深克隆
内存消耗低(共享引用)高(创建新对象)
数据隔离性弱(修改影响原对象)强(完全隔离)
实现复杂度简单(自动实现)复杂(需递归处理)
适用场景不可变对象/简单结构复杂对象层级/需要隔离修改
深度克隆进阶实现
  1. 序列化方案(需实现Serializable接口)
import java.io.*;class SerialCloneable implements Serializable {public Object deepClone() throws IOException, ClassNotFoundException {try (ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(this);try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis)) {return ois.readObject();}}}
}

     2.嵌套对象克隆测试

public static void main(String[] args) throws Exception {// 浅克隆测试Address addr = new Address("Beijing");Person original = new Person("Alice", addr);Person cloned = (Person) original.clone();cloned.address.city = "Shanghai";System.out.println(original.address.city); // 输出"Shanghai"// 深克隆测试DeepPerson deepOriginal = new DeepPerson("Bob", new Address("Guangzhou"));DeepPerson deepClone = (DeepPerson) deepOriginal.clone();deepClone.address.city = "Shenzhen";System.out.println(deepOriginal.address.city); // 保持"Guangzhou"
}

核心差异总结
  1. 对象关系拓扑:

    • 浅克隆:生成对象图与原对象共享叶节点
    • 深克隆:构建完全独立的对象树
  2. 内存模型表现: 

      

      3.修改传播特性:

       

最佳实践建议
  1. 优先考虑不可变对象设计
  2. 复杂对象推荐使用深克隆框架(如Apache Commons Lang3的SerializationUtils)
  3. 对于循环引用结构,需实现引用追踪机制
  4. 注意克隆过程中静态字段的处理
http://www.xdnf.cn/news/10264.html

相关文章:

  • 秒杀系统—5.第二版升级优化的技术文档三
  • Brighter 的线程模型:为何专用线程驱动异步消息泵
  • Python(十四)
  • Vue-自定义指令
  • *JavaScript中的Symbol类型:唯一标识符的艺术
  • # STM32F103 PA0到PA4多路ADC采集配置和采集程序
  • SQL进阶之旅 Day 9:高级索引策略
  • sass高阶应用
  • 基于Web的濒危野生动物保护信息管理系统设计(源码+定制+开发)濒危野生动物监测与保护平台开发 面向公众参与的野生动物保护与预警信息系统
  • resubmit v1.2.0 新特性支持类级别防止重复提交
  • 深度学习总结(40)
  • 数据集笔记:SeekWorld
  • 【Java笔记】Spring IoC DI
  • YOLOv8 移动端升级:借助 GhostNetv2 主干网络,实现高效特征提取
  • 【CC协议】知识共享许可协议(Creative Commons Licenses)体系解析
  • 注销微软账户
  • android 媒体框架之MediaCodec
  • MySQL中COUNT(*)、COUNT(1)和COUNT(字段名)的深度剖析与实战应用
  • 谷歌:贝叶斯框架优化LLM推理反思
  • CMake指令:list()
  • MySQL(48) 什么是ZEROFILL属性?
  • 宇树机器狗go2添加3d雷达(下)添加velodyne系列雷达
  • 《高等数学》(同济大学·第7版) 第一节《映射与函数》超详细解析
  • 数据库只更新特定字段的两种方式(先读后写 vs. 动态组织 SQL)-golang SQLx 实现代码(动态组织 SQL)
  • 索引的选择与Change Buffer
  • Linux进程信号
  • 车载诊断架构SOVD --- 车辆发现与建连
  • 项目:贪吃蛇实现
  • AI与智能驾驶的关系和原理:技术融合与未来展望-优雅草卓伊凡一、AI大模型基础原理与智能驾驶
  • 【Linux系列】Linux/Unix 系统中的 CPU 使用率