首先要知道的:

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

这里其实是复制了一个地址指向堆,studentAstudentC 两个引用都是指向同一个地址, 这就叫做引用拷贝

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=[看电影, 码代码])

可以看到浅拷贝之后:studentAstudentC是两个不同的地址了,说明clone()方法重新拷贝了一份对象,所以 studentA.setName("哈希"); 仅仅是修改了 studentA 对象。

但是 hobbies[0] = "看电影"; 却是联动的,对 studentAstudentC 两个对象都是有有影响的,说明这个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)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。

深拷贝把要复制的对象所引用的对象都复制了一遍

区别:

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

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

引用拷贝、对象拷贝、浅拷贝、深拷贝 到底是什么【详细例子介绍】相关推荐

  1. Java基础篇:对象拷贝:clone方法 以及 序列化

    我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...

  2. 谈谈Java开发中的对象拷贝

    在Java开发工作中,有很多时候我们需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息.这两个对象实例有可能是同一个类的两个实例,也可能是不同类的两个 ...

  3. BeanCopier 对象拷贝

    BeanCopier 对象拷贝 对象拷贝转为其他类的对象 对象数组拷贝转为其他类的对象数组 import java.util.List; import java.util.Map; import ja ...

  4. 深入浅出解释深拷贝、浅拷贝、对象拷贝、引用拷贝原理和应用

    拷贝总体上分为引用拷贝和对象拷贝. 1. 引用拷贝 创建一个指向对象的引用变量的拷贝. public class QuoteCopy {public static void main(String[] ...

  5. Python天天美味(22) - 拷贝对象(深拷贝deepcopy与浅拷贝copy)

    Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deep ...

  6. Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)

    http://www.jb51.net/article/15714.htm 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝 ...

  7. JS对象拷贝:深拷贝和浅拷贝

    摘要:对象拷贝,简而言之就是将对象再复制一份,但是,复制的方法不同将会得到不同的结果. 本文分享自华为云社区<js对象深浅拷贝,来,试试看!>,作者: 北极光之夜.. 一.速识概念: 对象 ...

  8. 将对象拷贝一份备用,改变原对象的属性时,为啥备份数据也改变了?(赋值、浅拷贝和深拷贝的区别)

    前言 前两天在写代码时碰到一个很奇怪的问题,我有一个对象person = {name: ''tianxin, age: 18};,我需要将person目前的数据拷贝一份备用let copyPerson ...

  9. 深拷贝——将对象拷贝到底

    假设我们有一个这样的需求,我们需要编辑修改一份表单,修改后提交之前想还原到之前的表单的值,这样我们就需要对原始表单有一个备份 // 原始表单 var form = {name: '张三',age: 1 ...

最新文章

  1. R语言ggplot2可视化删除所有分面图(facet_wrap可视化的facet结果)的标签实战(Remove facet_wrap labels)
  2. cryptogen (1)generate 生成证书举例
  3. Http / Get 和 Post 区别
  4. n 个整数的无序数组,找到每个元素后面比它大的第一个数,要求时间复杂度为 O(N)
  5. 一个人如果没有计划,那和咸鱼有什么区别!
  6. 【elasticsearch】如何部分更新文档 (partial update的使用)
  7. TP框架多上传域上传图片
  8. 2021-08-08索引在小数据量的时候用处不大,但在大数据的时候十分明显
  9. idea全局主题_2020年最新-IDEA最详细配置(配图文收藏版配置)
  10. python批量实现百度网盘链接有效性检测
  11. Kubernetes init 提示 [ERROR ImagePull]: failed to pull image registry.aliyuncs.com/google_containers/c
  12. 快手发布二季度及中期业绩:Q2收入191亿元 同比劲增48.8%
  13. 2019该怎么学unity3D游戏开发?
  14. 打开计算机 访问不到d盘,电脑d盘打不开怎么办,教你电脑d盘打不开怎么办
  15. VS2022中scanf返回值被忽略的原因及其解决方法
  16. 智慧实验室解决方案-最新全套文件
  17. 计算机专业c语言随堂练,华工C++随堂练习答案+2020春
  18. Python实现樱花飘落
  19. Wind River风河公司vxWorks嵌入式操作系统开发平台系列
  20. 计算机信息管理属于金融相关,中国人民银行招聘专业分类:哪些专业属于计算机信息管理类...

热门文章

  1. 教程1:Hello Behaviac
  2. FPGA Vs 单片机 -- 嵌入式设计的另一种方法
  3. WebSocket断开原因
  4. [BZOJ3698] XWW的难题 网络流
  5. 2021国防科技大学计算机学院无军籍考研409分经验贴(数一+英一+834)
  6. 1 什么叫多媒体计算机,选择1多媒体计算机中的媒体信息是指()文字声音.ppt
  7. 脚下,梦開始的地方——七月总结
  8. 【校招VIP】产品项目分析之优势或不足
  9. 2.什么是JAVA内存模型?
  10. 3dmaxobj导出选项_3dmax导出obj没有贴图该怎么办