Java中深拷贝和浅拷贝详解学习

2024-05-27 20:20
文章标签 java 学习 详解 拷贝 中深

本文主要是介绍Java中深拷贝和浅拷贝详解学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、什么是深拷贝?什么是浅拷贝?

Java中深拷贝和浅拷贝都是与Java中对象的复制有关。Java 中的深拷贝和浅拷贝通常通过实现 Cloneable 接口并重写 clone() 方法来实现。

浅拷贝:

在浅拷贝中,只有对象的基本数据类型属性被复制,而对象的引用类型属性则只是被复制了引用。这意味着新对象和原对象共享引用类型对象。

深拷贝:

在深拷贝中,会递归地复制对象及其所有子对象(无论是基本数据类型还是引用对象),确保新对象与原始对象完全独立。

二、浅拷贝示例

@Data
public class Teacher implements Cloneable{private String name;private int age;private School school;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public Teacher(String name, int age, School school) {this.name = name;this.age = age;this.school = school;}
}@Data
@Accessors(chain = true)
public class Teacher implements Cloneable{private String name;private int age;private School school;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();      //浅拷贝}public Teacher(String name, int age, School school) {this.name = name;this.age = age;this.school = school;}
}@Slf4j
public class Main {public static void main(String[] args) throws CloneNotSupportedException {School school = new School("AAA School");Teacher teacher = new Teacher("Alice", 20, school);Teacher backTeacher = (Teacher) teacher.clone();backTeacher.setName("Tom");backTeacher.setAge(18);backTeacher.getSchool().setName("BBB School");//将对象序列化为json字符串进行日志打印String jsonTeacher = JSON.toJSONString(teacher);String jsonBackTeacher = backTeacher.toString();log.info("[Teacher] jsonTeacher name is : {}", jsonTeacher);log.info("[Teacher] jsonBackTeacher name is : {}", jsonBackTeacher);}
}

输出结果:

15:46:02.300 [main] INFO com.example.demo.entity.Main - [Teacher] teacher name is : {"age":20,"name":"Alice","school":{"name":"BBB School"}}
15:46:02.303 [main] INFO com.example.demo.entity.Main - [Teacher] teacher name is : Teacher(name=Tom, age=18, school=School(name=BBB School))

可以看到浅拷贝后,基本的数据类型修改没有影响,而对于引用对象数据修改后,原对象和复制的对象会联动修改

三、深拷贝示例

@Data
@Accessors(chain = true)
public class Teacher implements Cloneable{private String name;private int age;private School school;@Overrideprotected Object clone() throws CloneNotSupportedException {Teacher cloneTeacher = (Teacher) super.clone();cloneTeacher.school = (School) school.clone(); //深拷贝School对象return cloneTeacher;}public Teacher(String name, int age, School school) {this.name = name;this.age = age;this.school = school;}
}@Data
@Accessors(chain = true)
public class School implements Cloneable{private String name;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public School(String name) {this.name = name;}
}@Slf4j
public class Main {public static void main(String[] args) throws CloneNotSupportedException {School school = new School("AAA School");Teacher teacher = new Teacher("Alice", 20, school);Teacher backTeacher = (Teacher) teacher.clone();backTeacher.setName("Tom");backTeacher.setAge(18);backTeacher.getSchool().setName("BBB School");//将对象序列化为json字符串进行日志打印String jsonTeacher = JSON.toJSONString(teacher);String jsonBackTeacher = backTeacher.toString();log.info("[Teacher] jsonTeacher name is : {}", jsonTeacher);log.info("[Teacher] jsonBackTeacher name is : {}", jsonBackTeacher);}
}

输出结果:

16:49:45.213 [main] INFO com.example.demo.entity.Main - [Teacher] jsonTeacher name is : {"age":20,"name":"Alice","school":{"name":"AAA School"}}
16:49:45.215 [main] INFO com.example.demo.entity.Main - [Teacher] jsonBackTeacher name is : Teacher(name=Tom, age=18, school=School(name=BBB School))

可以看到深拷贝后,原对象和拷贝后的对象无论是基本数据还是引用对象的数据都相互独立,互不影响。

四、项目中如何实现深拷贝

在项目中会借助fastjson库通过序列化+反序列化的方式实现对于复制对象的深拷贝
代码示例如下:

@Slf4j
public class Main {/*** 借助fastjson库 通过序列化 + 反序列化的方式实现对象的深拷贝** @param object* @param <T>* @return*/public static <T> T deepCopy(T object) {String jsonString = JSON.toJSONString(object);return JSON.parseObject(jsonString, (Class<? extends T>) object.getClass());}public static void main(String[] args) throws CloneNotSupportedException {School school = new School("AAA School");Teacher teacher = new Teacher("Alice", 20, school);//Teacher backTeacher = (Teacher) teacher.clone();Teacher backTeacher = deepCopy(teacher);backTeacher.setName("Tom");backTeacher.setAge(18);backTeacher.getSchool().setName("BBB School");//将对象序列化为json字符串进行日志打印String jsonTeacher = JSON.toJSONString(teacher);String jsonBackTeacher = backTeacher.toString();log.info("[Teacher] jsonTeacher name is : {}", jsonTeacher);log.info("[Teacher] jsonBackTeacher name is : {}", jsonBackTeacher);}
}

输出结果:

17:27:21.649 [main] INFO com.example.demo.entity.Main - [Teacher] jsonTeacher name is : {"age":20,"name":"Alice","school":{"name":"AAA School"}}
17:27:21.653 [main] INFO com.example.demo.entity.Main - [Teacher] jsonBackTeacher name is : Teacher(name=Tom, age=18, school=School(name=BBB School))

这篇关于Java中深拷贝和浅拷贝详解学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1008495

相关文章

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

java中long的一些常见用法

《java中long的一些常见用法》在Java中,long是一种基本数据类型,用于表示长整型数值,接下来通过本文给大家介绍java中long的一些常见用法,感兴趣的朋友一起看看吧... 在Java中,long是一种基本数据类型,用于表示长整型数值。它的取值范围比int更大,从-922337203685477

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c