克隆、深拷贝与浅拷贝区别

简介: 克隆、深拷贝与浅拷贝区别

克隆、深拷贝与浅拷贝区别



1,克隆:

❀❀业务需求:保留原来的对象,但是需要一个在原来对象的信息上进行修改点信息的对象,需要使用到克隆技术-------clone();

(因为使用clone() 拷贝出来的对象,有自己的内存地址,而不是跟被拷贝对象一样指向同一个内存地址。

ps:细节:对象要使用clone()方法前,对象的类需要先实现Cloneable接口

ps:▪clone() 跟 new 区别:new 完的对象没有原来对象的已有数据信息。

例如原来对象(学生对象:数据信息:小红、20、 100),而new 一个对象的话,这没有数据。

▪另外如果是采取直接定义引用变量stu2直接执行已经存在的学生对象stu1,两个引用指向同一个内存地址,影响是同步的,不符合咱的业务需求(原来的对象不被新产生的类所影响)

代码:

1
2
3
4
5
6
7
Student stu1 = new Student(“小红”, 20, 100);
Student stu2 = stu1;
此刻修改stu2,例如 stu2.setName(“小芳”);
则stu1、stu2的姓名都变成了小芳。


 

2,深拷贝与浅拷贝区别:


2-1:先搞懂 “引用对象”跟“对象引用”,根据语文的主干理解,“引用对象”跟“对象引用”

引用对象-------主干是对象

对象引用-------主干是引用

“引用对象”跟“对象引用”的区别:简单理解变成变成了对象与引用的区别

例子 Class1 A = new Class1();

我们知道对象都是new 出来的,显然这里的对象(引用对象)就是 new Class1();

而引用(对象引用)就是A(因为本质讲,引用就是C语言的指针,指向的作用)。平时没考察到底层原理的,通俗理解:A就是new Class1() 起的别名。

 

2-2:深拷贝与浅拷贝区别:

深拷贝是针对较为复杂的object类型数据

✿浅拷贝定义:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。

即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。

✿深拷贝定义:深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存

当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

 

(1)情况一:类只有基本类型的属性,没有对象引用属性。

这时候只需要clone()就可以实现克隆啦(默认情况的clone()就是浅拷贝)

 

(2)情况二:类除了基本类型的属性,还有对象引用属性。

实现业务采取方式一:如果只是想刚才那样,类实现Cloneable接口,然后类重写clone()方法,那么会导致两个对象的内部的对象引用属性又指向同一个内存地址。

解决1:既然内部对象引用属性出现了之前的指向同一个内存地址问题?----对于内部的对象属性的所引用的类也使用类实现接口Cloneable,重写clone()方法来解决。

解决2:利用序列化与反序列化实现(序列化就是将对象写到流中的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以

复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再反序列化从流中将其读出来,即可实现深拷贝。)这种方式才是真正意义上的的深度克隆。

 

2-3:深拷贝与浅拷贝区别:是否拷贝了java(引用)对象。深拷贝拷贝引用对象,而浅拷贝没有拷贝引用对象。浅拷贝只复制指向某个对象的指针,而不复制对象本身,

新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

 

2-4、总结:实现对象克隆有两种方式:

1). 实现Cloneable接口并重写Object类中的clone()方法;

2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,这种方式才是真正意义上的的深度克隆。

 


目录
相关文章
|
10月前
|
人工智能 JavaScript 前端开发
一段 JavaScript 代码,集成网站AI语音助手
根据本教程,只需通过白屏化的界面操作,即可快速构建一个专属的AI智能体。
|
Kubernetes 测试技术 数据库
详解微服务应用灰度发布最佳实践
相对于传统软件研发,微服务架构下典型的需求交付最大的区别在于有了能够小范围真实验证的机制,且交付单位较小,风险可控,灰度发布可以弥补线下测试的不足。本文从 DevOps 视角概述灰度发布实践,介绍如何将灰度发布与 DevOps 工作融合,快来了解吧~
33245 19
|
存储 Java 开发者
HashSet和TreeSet教你重新认识Java集合的无序与有序
【10月更文挑战第14天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了它们分别实现无序和有序存储的机制。通过理解HashSet基于哈希表的无序特性和TreeSet利用红黑树实现的有序性,帮助开发者更好地选择合适的集合类型以满足不同的应用场景。
273 2
|
人工智能 编解码 自然语言处理
魔搭社区每周速递(8.4-8.10)
315个模型、36个数据集、62个创新应用、5篇应用文章
|
Java 开发者 微服务
深入解析@SpringBootApplication注解:简化Spring Boot应用的配置
在现代的Java开发中,Spring Boot框架成为了构建微服务和快速开发应用的首选。Spring Boot的成功部分归功于其简化的配置和约定大于配置的理念。而`@SpringBootApplication`注解则是Spring Boot应用的入口,负责自动配置和启动Spring Boot应用。本文将深入探讨`@SpringBootApplication`注解的作用、用法,以及在Spring Boot应用中的应用场景。
1820 1
|
关系型数据库 MySQL 数据库
MySQL实战基础知识入门(6):mysql使用mysqldump导出数据出错的解决方案
MySQL实战基础知识入门(6):mysql使用mysqldump导出数据出错的解决方案
427 0
|
Java API 开发者
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
BeanDefinitionBuilder类为Spring框架中的Bean定义提供了灵活且强大构建方式,通过API,开发者能够轻松创建和配置Bean,无需依赖繁琐的XML配置或注解。
464 2
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
|
前端开发 JavaScript NoSQL
打造个人博客:从零到一的全栈开发之旅
【8月更文挑战第31天】 想象一下,一个完全由你掌控的空间——你的个人博客。在这里,文字是你的画笔,代码是你的声音。本文将带你走进全栈开发的世界,一步步构建起你自己的网络空间。无论你是编程新手还是想扩展技能边界的老手,这篇文章都将为你提供一条清晰的路径。我们将从基础的工具选择开始,逐步深入到前端和后端的开发,最终完成一个功能完备的个人博客。让我们一起探索代码的魅力,实现从无到有的创造旅程。
|
设计模式 Java 开发者
Java一分钟之-Swing组件:JTable, JTree, JTextArea
本文介绍了Java Swing的三个关键组件:`JTable`、`JTree`和`JTextArea`,用于数据展示和用户输入。`JTable`展示二维数据,如表格;`JTree`展示层次结构数据,如文件系统;`JTextArea`则用于多行文本输入和显示。每个组件都提供了示例代码,并列出常见问题及避免方法,如数据源未设置、滚动面板缺失等。理解并掌握这些组件,能帮助开发者创建高效用户界面。
370 0
|
NoSQL Redis
Redis系列学习文章分享---第五篇(Redis实战篇--优惠券秒杀,全局唯一id 添加优惠券 实现秒杀下单 库存超卖问题分析 乐观锁解决超卖 实现一人一单功能 集群下的线程并发安全问题)
Redis系列学习文章分享---第五篇(Redis实战篇--优惠券秒杀,全局唯一id 添加优惠券 实现秒杀下单 库存超卖问题分析 乐观锁解决超卖 实现一人一单功能 集群下的线程并发安全问题)
401 0