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

article/2025/6/23 6:15:08

浅克隆与深克隆在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.hkcw.cn/article/BGLpmYjhCE.shtml

相关文章

【HW系列】—日志介绍

文章目录 一、日志介绍二、Apache日志详解1. 日志存放位置2. 日志类型3. 日志级别4. 常用日志分析命令(Linux环境) 三、IIS日志详解四、日志分析工具:360星图 一、日志介绍 为什么要使用日志 故障诊断:快速定位系统错误根源安全审…

cuda_fp8.h错误

现象: cuda_fp8.h错误 原因: CUDA Toolkit 小于11.8,会报fp8错误,因此是cuda工具版本太低。通过nvcc --version查看 CUDA Toolkit 是 NVIDIA 提供的一套 用于开发、优化和运行基于 CUDA 的 GPU 加速应用程序的工具集合。它的核心作用是让开发…

内容中台构建数字化管理新路径

数字化内容管理核心架构 现代企业数字化内容管理的核心架构依托于动态元数据架构构建策略与多源数据智能整合体系的双重支撑。通过建立三层架构模型——数据采集层、逻辑处理层与应用服务层,系统能够实现跨平台内容资产的统一索引与语义关联。其中,Bakl…

【连载21】基础智能体的进展与挑战综述-交互风险

20. 智能体外部安全性:交互风险 随着人工智能智能体的发展以及与日益复杂的环境互动,与这些互动相关的安全风险已成为一个关键问题。本章聚焦于人工智能智能体与记忆系统、物理和数字环境及其他智能体的互动。这些互动使人工智能智能体面临各种脆弱性&a…

【Day41】

DAY 41 简单CNN 知识回顾 数据增强卷积神经网络定义的写法batch归一化:调整一个批次的分布,常用与图像数据特征图:只有卷积操作输出的才叫特征图调度器:直接修改基础学习率 卷积操作常见流程如下: 1. 输入 → 卷积层 →…

C++:参数传递方法(Parameter Passing Methods)

目录 1. 值传递(Pass by Value) 2. 地址传递(Pass by Address) 3. 引用传递(Pass by Reference) 数组作为函数参数(Array as Parameter) 数组作为函数返回值 什么是函数&#xff…

【iOS】方法交换

方法交换 method-swizzling是什么相关API方法交换的风险method-swizzling使用过程中的一次性问题在当前类中进行方法交换类方法的方法交换 方法交换的应用 method-swizzling是什么 method-swizzling的含义是方法交换,他的主要作用是在运行的时候将一个方法的实现替…

GoogLeNet网络模型

GoogLeNet网络模型 诞生背景 在2014年的ImageNet图像识别挑战赛中,一个GoogLeNet的网络架构大放异彩,与VGG不同的是,VGG用的是3*3的卷积,而GoogLeNet从1*1到7*7的卷积核都用,也就是使用不同大小的卷积核组合。 网络…

Linux:动静态库

一:什么是库 库是写好的,现有的,成熟的可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人都从零开始写,因此库的存在一样非同寻常 本质上库是一种可执行代码的二进制形式,可以被操作…

【图像处理入门】2. Python中OpenCV与Matplotlib的图像操作指南

一、环境准备 import cv2 import numpy as np import matplotlib.pyplot as plt# 配置中文字体显示(可选) plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False二、图像的基本操作 1. 图像读取、显示与保存 使用OpenCV…

设计模式——装饰器设计模式(结构型)

摘要 文中主要介绍了装饰器设计模式,它是一种结构型设计模式,可在不改变原有类代码的情况下,动态为对象添加额外功能。文中详细阐述了装饰器模式的角色、结构、实现方式、适合场景以及实战示例等内容,还探讨了其与其他设计模式的…

生活小记啊

最近生活上的事情还是蛮多的,想到哪写到哪。 工作 三月的某个周六,正在加班写技术方案,大晚上写完了听到调动通知,要去新的团队了。 还是蛮不舍的,看着产品从无到有,一路走过来,倾注了不少感…

【android bluetooth 案例分析 04】【Carplay 详解 2】【Carplay 连接之手机主动连车机】

1. 背景 在【android bluetooth 案例分析 04】【Carplay 详解 1】【CarPlay 在车机侧的蓝牙通信原理与角色划分详解】中我们从整理上介绍了车机中 carplay 相关基础概念。 本节 将详细分析 iphone手机主动 连接 车机carplay 这一过程。 先回顾一下 上一节, carpla…

【Kotlin】数字字符串数组集合

【Kotlin】简介&变量&类&接口 【Kotlin】数字&字符串&数组&集合 文章目录 Kotlin_数字&字符串&数组&集合数字字面常量显式转换数值类型转换背后发生了什么 运算字符串字符串模板字符串判等修饰符数组集合通过序列提高效率惰性求值序列的操…

FreeCAD源码分析: 串行化工具

本文分析FreeCAD中的串行化工具。 注1:限于研究水平,分析难免不当,欢迎批评指正。 注2:文章内容会不定期更新。 零、预修 0.1 QDataStream 0.2 Boost.Iostreams 0.3 Zipios 0.4 Xerces-C 一、核心组件 1.1 Base::Writer 1.2 Ba…

【R语言编程绘图-plotly】

安装与加载 在R中使用plotly库前需要安装并加载。安装可以通过CRAN进行,使用install.packages()函数。加载库使用library()函数。 install.packages("plotly") library(plotly)测试库文件安装情况 # 安装并加载必要的包 if (!requireNamespace("p…

设计模式——系统数据建模设计

摘要 本文主要介绍了UML在软件系统分析和设计中的应用,详细阐述了六大类关系(泛化、实现、依赖、关联、聚合、组合)及其在UML类图中的表示方法,并通过具体例子说明了这些关系在实际编程中的应用。同时,文章还概述了UM…

37. Sudoku Solver

题目描述 37. Sudoku Solver 回溯 class Solution {vector<vector<bool>> row_used;vector<vector<bool>> col_used;vector<vector<bool>> box_used;public:void solveSudoku(vector<vector<char>>& board) {row_used.r…

【Java开发日记】基于 Spring Cloud 的微服务架构分析

目录 1、Spring Cloud 2、Spring Cloud 的核心组件 1. Eureka&#xff08;注册中心&#xff09; 2. Zuul&#xff08;服务网关&#xff09; 3. Ribbon&#xff08;负载均衡&#xff09; 4. Hystrix&#xff08;熔断保护器&#xff09; 5. Feign&#xff08;REST转换器&a…

进程间通信IV System V 系列(linux)

目录 消息队列 原理 操作 补充概念 信号量 (原子性计数器) 原理 操作 (和共享内存相似) 总结 小知识 消息队列 原理 在内核中建立一个队列&#xff0c;进程可以相互进行通信&#xff0c;通过队列进行IPC&#xff0c;就是进程之间发送带类型的数据块。 操作 接口和共享…