引用拷贝、对象拷贝、浅拷贝、深拷贝 到底是什么【详细例子介绍】
首先要知道的:
Java的数据类型分为基本数据类型和引用数据类型。
拷贝一个对象,可以使用 Cloneable接口
的clone()
方法。
对象拷贝分为 浅拷贝 和 深拷贝,这两种拷贝都是从引用拷贝 引出的。
通过下面的例子你就可以明白这三者的区别了。
1、引用拷贝
引用拷贝 简单的说就是通过 =
地址赋值。
class TestClone {public static void main(String[] args) throws CloneNotSupportedException {String[] hobbies = new String[]{"打篮球", "码代码"};Student studentA = new Student(1, "HaC", hobbies);System.out.println("------------引用拷贝----------------");Student studentB = studentA; //复制引用,这是对象地址赋值studentB.setId(2); //studentA studentB 都是指向同一个地址hobbies[0] = "看电影";System.out.println("studentA:" + studentA);System.out.println("studentC:" + studentB);System.out.println("studentA == studentB 的结果:"+(studentA == studentB));}
}@AllArgsConstructor
@Data
public class Student implements Cloneable {int id;String name;String[] hobbies;
}
输出:
------------引用拷贝----------------
studentA:Student(id=2, name=HaC, hobbies=[看电影, 码代码])
studentC:Student(id=2, name=HaC, hobbies=[看电影, 码代码])
studentA == studentB 的结果:true
这里其实是复制了一个地址指向堆,studentA
、studentC
两个引用都是指向同一个地址
, 这就叫做引用拷贝
。
2、浅拷贝
Cloneable接口
提供了一个clone()
方法进行 对象拷贝
,我们可以通过实现clone()
方法实现浅拷贝或者深拷贝。
浅拷贝可以创建一个对象的副本,把基本数据类型和final修饰的数据类型 复制一份,但是如果是引用数据类型,只能复制地址。
class TestClone {public static void main(String[] args) throws CloneNotSupportedException {String[] hobbies = new String[]{"打篮球", "码代码"};Student studentA = new Student(1, "HaC", hobbies);System.out.println("------------浅拷贝----------------");Student studentC = (Student) studentA.clone();System.out.println("studentA:" + studentA);System.out.println("studentC:" + studentC);System.out.println("studentA == studentC 的结果:" + (studentA == studentC));studentA.setName("哈希");hobbies[0] = "看电影";System.out.println("studentA:" + studentA);System.out.println("studentC:" + studentC);}
}@AllArgsConstructor
@Data
public class Student implements Cloneable {int id;String name;String[] hobbies;@Overrideprotected Object clone() throws CloneNotSupportedException {//浅拷贝return super.clone();}
}
输出:
------------浅拷贝----------------
studentA:Student(id=1, name=HaC, hobbies=[打篮球, 码代码])
studentC:Student(id=1, name=HaC, hobbies=[打篮球, 码代码])
studentA == studentC 的结果:false
studentA:Student(id=1, name=哈希, hobbies=[看电影, 码代码])
studentC:Student(id=1, name=HaC, hobbies=[看电影, 码代码])
可以看到浅拷贝之后:studentA
和 studentC
是两个不同的地址了,说明clone()
方法重新拷贝了一份对象,所以 studentA.setName("哈希");
仅仅是修改了 studentA
对象。
但是 hobbies[0] = "看电影";
却是联动的,对 studentA
、studentC
两个对象都是有有影响的,说明这个hobbies
字段是个地址拷贝
。
3、深拷贝
浅拷贝是无法把引用对象的值也拷贝的,只是拷贝了地址。
所以如果你要把地址对应的 值也拷贝一份,可以使用深拷贝,实现的原理就是 在clone()
方法 再拷贝一份你需要的对象。
class TestClone {public static void main(String[] args) throws CloneNotSupportedException {String[] hobbies = new String[]{"打篮球", "码代码"};Student studentA = new Student(1, "HaC", hobbies);System.out.println("------------深拷贝----------------");Student studentC = (Student) studentA.clone();System.out.println("studentA:" + studentA);System.out.println("studentC:" + studentC);System.out.println("studentA == studentC 的结果:" + (studentA == studentC));studentA.setName("哈希");hobbies[0] = "看电影";System.out.println("studentA:" + studentA);System.out.println("studentC:" + studentC);}
}@AllArgsConstructor
@Data
public class Student implements Cloneable {int id;String name;String[] hobbies;@Overrideprotected Object clone() throws CloneNotSupportedException {// 深拷贝,现在将String[]复制一份并重新set进来Student student = (Student) super.clone();student.setHobbies(student.getHobbies().clone());return student;}
}
输出:
------------深拷贝----------------
studentA:Student(id=1, name=HaC, hobbies=[打篮球, 码代码])
studentC:Student(id=1, name=HaC, hobbies=[打篮球, 码代码])
studentA == studentC 的结果:false
studentA:Student(id=1, name=哈希, hobbies=[看电影, 码代码])
studentC:Student(id=1, name=HaC, hobbies=[打篮球, 码代码])
深拷贝
会 毫无保留地把所有对象都拷贝一份出来,然后修改就是自己的对象。
总结:
1、深拷贝和浅拷贝都是对象拷贝,引用拷贝只是赋值了一个地址,并不是真正的对象的值。
2、浅拷贝
浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址
(1) 对于基本数据类型、final修饰 的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个。
(2) 对于引用类型,比如数组或者类对象,因为引用类型是引用传递,所以浅拷贝只是把内存地址赋值给了成员变量,它们指向了同一内存空间。改变其中一个,会对另外一个也产生影响,联动。
3、深拷贝
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
深拷贝把要复制的对象所引用的对象都复制了一遍
区别:
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
引用拷贝、对象拷贝、浅拷贝、深拷贝 到底是什么【详细例子介绍】相关推荐
- Java基础篇:对象拷贝:clone方法 以及 序列化
我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...
- 谈谈Java开发中的对象拷贝
在Java开发工作中,有很多时候我们需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息.这两个对象实例有可能是同一个类的两个实例,也可能是不同类的两个 ...
- BeanCopier 对象拷贝
BeanCopier 对象拷贝 对象拷贝转为其他类的对象 对象数组拷贝转为其他类的对象数组 import java.util.List; import java.util.Map; import ja ...
- 深入浅出解释深拷贝、浅拷贝、对象拷贝、引用拷贝原理和应用
拷贝总体上分为引用拷贝和对象拷贝. 1. 引用拷贝 创建一个指向对象的引用变量的拷贝. public class QuoteCopy {public static void main(String[] ...
- Python天天美味(22) - 拷贝对象(深拷贝deepcopy与浅拷贝copy)
Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deep ...
- Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
http://www.jb51.net/article/15714.htm 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝 ...
- JS对象拷贝:深拷贝和浅拷贝
摘要:对象拷贝,简而言之就是将对象再复制一份,但是,复制的方法不同将会得到不同的结果. 本文分享自华为云社区<js对象深浅拷贝,来,试试看!>,作者: 北极光之夜.. 一.速识概念: 对象 ...
- 将对象拷贝一份备用,改变原对象的属性时,为啥备份数据也改变了?(赋值、浅拷贝和深拷贝的区别)
前言 前两天在写代码时碰到一个很奇怪的问题,我有一个对象person = {name: ''tianxin, age: 18};,我需要将person目前的数据拷贝一份备用let copyPerson ...
- 深拷贝——将对象拷贝到底
假设我们有一个这样的需求,我们需要编辑修改一份表单,修改后提交之前想还原到之前的表单的值,这样我们就需要对原始表单有一个备份 // 原始表单 var form = {name: '张三',age: 1 ...
最新文章
- R语言ggplot2可视化删除所有分面图(facet_wrap可视化的facet结果)的标签实战(Remove facet_wrap labels)
- cryptogen (1)generate 生成证书举例
- Http / Get 和 Post 区别
- n 个整数的无序数组,找到每个元素后面比它大的第一个数,要求时间复杂度为 O(N)
- 一个人如果没有计划,那和咸鱼有什么区别!
- 【elasticsearch】如何部分更新文档 (partial update的使用)
- TP框架多上传域上传图片
- 2021-08-08索引在小数据量的时候用处不大,但在大数据的时候十分明显
- idea全局主题_2020年最新-IDEA最详细配置(配图文收藏版配置)
- python批量实现百度网盘链接有效性检测
- Kubernetes init 提示 [ERROR ImagePull]: failed to pull image registry.aliyuncs.com/google_containers/c
- 快手发布二季度及中期业绩:Q2收入191亿元 同比劲增48.8%
- 2019该怎么学unity3D游戏开发?
- 打开计算机 访问不到d盘,电脑d盘打不开怎么办,教你电脑d盘打不开怎么办
- VS2022中scanf返回值被忽略的原因及其解决方法
- 智慧实验室解决方案-最新全套文件
- 计算机专业c语言随堂练,华工C++随堂练习答案+2020春
- Python实现樱花飘落
- Wind River风河公司vxWorks嵌入式操作系统开发平台系列
- 计算机信息管理属于金融相关,中国人民银行招聘专业分类:哪些专业属于计算机信息管理类...
热门文章
- 教程1:Hello Behaviac
- FPGA Vs 单片机 -- 嵌入式设计的另一种方法
- WebSocket断开原因
- [BZOJ3698] XWW的难题 网络流
- 2021国防科技大学计算机学院无军籍考研409分经验贴(数一+英一+834)
- 1 什么叫多媒体计算机,选择1多媒体计算机中的媒体信息是指()文字声音.ppt
- 脚下,梦開始的地方——七月总结
- 【校招VIP】产品项目分析之优势或不足
- 2.什么是JAVA内存模型?
- 3dmaxobj导出选项_3dmax导出obj没有贴图该怎么办