参考:
Java核心技术
https://blog.csdn.net/zhangjg_blog/article/details/18369201
https://www.jianshu.com/p/94dbef2de298

拷贝

  • 基本数据类型的拷贝
  • 引用数据类型的拷贝
  • 深拷贝和浅拷贝
    • 浅拷贝
      • 示例
    • 深拷贝
      • 示例
  • 如何进行深拷贝
  • 实现深拷贝的示例
    • 主函数
    • Person类的定义
    • Address类的定义

基本数据类型的拷贝

Object类中的clone()方法实现的是浅拷贝,对于基本数据类型,由于是直接复制值,原对象和克隆对象(副本)之间状态各自独立,不会相互影响。如果对象中所有的数据域都是基本数据类型,浅拷贝这些域没有任何问题。因为此时,浅拷贝和深拷贝之间不存在差别。

引用数据类型的拷贝

但是如果原对象包含子对象(即另一个类的对象)的引用,浅拷贝对应域就会得到相同子对象的另一个引用。也就是说,浅拷贝在该属性上并没有复制子对象的状态(内容),而只是复制了引用的值。这样一来,原对象和克隆的对象仍然会共享一些信息。这可能就会造成,当我们对其中一个引用数据类型所指向的对象的状态(内容)进行改变的时候,另一个复制版本也会受到改动的影响。当然如果共享的子对象是不可变的,那么这种共享就是安全的,但通常子对象都是可变的。为了避免出现这种情况,就必须重新定义clone实现深拷贝。

深拷贝和浅拷贝

通过前面的讲述,我们可以看出,浅拷贝和深拷贝的特点。

浅拷贝

如果属性是基本数据类型,浅拷贝得到的就是基本数据类型的值;如果属性是内存地址(引用类型,称为子对象),浅拷贝得到的就是子对象的另一个引用 。因此对于原对象和克隆对象的子对象,2者引用类型的数据仍指向同一个内存空间。如果其中一个对象改变了这个地址,就会影响到另一个对象。

示例


借用Java核心技术中的例子来解释浅拷贝,Employee类的属性如下。

public class Employee {String name;double salary;Date hireday;
}

由于name和hireDay是引用类型数据,所以在进行浅拷贝之后,原对象和克隆对象中对应的属性都指向同一块内存存储空间。

深拷贝

深拷贝和浅拷贝唯一的不同就在于对引用类型数据的处理上。浅拷贝得到的是子对象的另一个引用,而深拷贝的得到一个存放了子对象状态的新的空间。

示例

深拷贝的结果就如下。原对象和克隆对象所有的属性都存在独立的空间中,2者不存在共享的存储空间。

如何进行深拷贝

如果想要深拷贝一个对象,这个对象所属的类必须实现Cloneable接口,并重写clone方法,而且在clone方法的内部,把该对象引用的其他对象(即子对象)也要clone一份,这就要求那些子对象所属的类也必须要实现Cloneable接口并且实现clone方法。值得注意的是,Cloneable接口只是一个标记接口,而标记接口并不包含任何方法。事实上,clone方法存在于Object类中。

实现深拷贝的示例

主函数

package ch6;public class CopyTest {public static void main(String[] args) {Person p1 = new Person("zhao",20,"上海市静安区","241001");System.out.println("修改前p1 = "+p1);// 实现深拷贝Person p1copy = p1.clone();// 修改克隆对象的状态p1copy.getAddr().setAddress("合肥市滨湖新区");System.out.println("p1copy修改后p1 = "+p1);System.out.println("p1copy = "+p1copy);}
}

Person类的定义

package ch6;public class Person implements Cloneable{private String name;private int age;private Address addr; // 引用数据类型public Person(){};public Person(String name,int age,String address,String postcode){this.name = name;this.age  = age;addr = new Address(address,postcode);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Address getAddr() {return addr;}public void setAddr(Address addr) {this.addr = addr;}@Overridepublic String toString() {return "Person["+"name : "+name+",age :"+age+","+addr.toString()+" ]";}@Overridepublic Person clone() {try {//Person cloned = (Person)super.clone();// 注意1:拷贝引用数据类型(如果不重写Address类中的clone方法则下面语句报编译错)// the method clone() from type Object is not visiblecloned.addr = (Address)addr.clone();return cloned;} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}

Address类的定义

package ch6;public class Address implements Cloneable{private String address;private String postcode;public Address(){}public Address(String address,String postcode){this.address = address;this.postcode = postcode;}public void setAddress(String address) {this.address = address;}public void setPostcode(String postcode) {this.postcode = postcode;}@Overridepublic String toString() {return "address ["+address+","+postcode+"]";}@Overridepublic Address clone() {try {return (Address)super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}

Java中的深拷贝与浅拷贝相关推荐

  1. Java中的深拷贝与浅拷贝浅析

    为什么需要拷贝?   拷贝的对象可能包含一些已经修改过的属性,而new出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的"状态"的时候,就需要clone( ...

  2. 谈一谈Java中的深拷贝和浅拷贝

    在 Java 开发中,对象拷贝或者说对象克隆是常有的事,对象克隆最终都离不开直接赋值.浅拷贝.深拷贝 这三种方式,其中直接赋值应该是我们最常用的一种方式吧,对于浅拷贝和深拷贝可能用的少,所以或多或少存 ...

  3. python怎么避免浅拷贝_详谈Python中的深拷贝和浅拷贝

    在平时工作中,经常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题.为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用.为了生成这个副本,就产生了拷贝. ...

  4. Java 深入理解深拷贝和浅拷贝区别

    title: Java 深入理解深拷贝和浅拷贝区别 date: 2021-6-19 updated: 2021-6-19 tags: Java 深拷贝和浅拷贝 categories: 面试 Java ...

  5. python中的深拷贝与浅拷贝

    浅拷贝的时候,修改原来的对象,深拷贝的对象不会发生改变. 对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷贝这个对象,而只是拷 ...

  6. C语言中的深拷贝和浅拷贝

    http://www.cnblogs.com/zhanggaofeng/p/5421804.html C语言中的深拷贝和浅拷贝 //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_N ...

  7. python中关于深拷贝和浅拷贝的详解

    python中关于深拷贝和浅拷贝的详解 概述 在python的语法中,有两种变量的拷贝方式 一种是深拷贝,一种是浅拷贝 我们先说深拷贝 语法 这里需要通过导入系统的copy模块中的deepcopy才可 ...

  8. vb.net中递归退到最外层_面试题被问到再也不慌,深究JavaScript中的深拷贝与浅拷贝...

    " 点个关注,养成习惯,带你python爬虫的过程中学习前端 " JavaScript中的深拷贝和浅拷贝是前端面试中频繁被问到的一道题, 于是我也自己去查阅了一些资料, 然后动手敲 ...

  9. js中的深拷贝和浅拷贝区别

    js中的深拷贝和浅拷贝与值传递和引用传递有着些许的关联,都是根据堆栈中数据的储存来传递数据. 下面主要说一下我对深拷贝和浅拷贝的理解: 简单举个例子来说明:当我们声明一个a变量并且赋值,并且让b等于a ...

  10. python深复制与浅复制_Python中的深拷贝和浅拷贝详解

    要说清楚Python中的深浅拷贝,需要搞清楚下面一系列概念: 变量-引用-对象(可变对象,不可变对象)-切片-拷贝(浅拷贝,深拷贝) [变量-对象-引用] 在Python中一切都是对象,比如说:3, ...

最新文章

  1. mysql插入大量数据
  2. 2018ACM四川省赛G.Grisaia(超棒的杜教筛好题)
  3. 博客园是否提供“我参与的主题”功能?
  4. 还原出厂设置 擦除frp_如何备份,擦除和还原Apple Watch
  5. 危难时刻,每个人都应该站出来
  6. f(x)和g(x)分别是概率密度函数,h(x)=f(x)g(x)还会是概率密度函数么?
  7. AAAI-2021-RE-Progressive Multitask Learning with Controlled Information Flow for Joint Entity and Re
  8. JNPF快速开发平台-业务流程系统(BPM)开发方案
  9. JavaWeb笔记(五)后端
  10. 怎样用CSS画一个三角形
  11. 服务器 控制台 的作用是,电脑中的MMC控制台的作用和用法是什么?
  12. 使用html2canvas和jspdf把网页保存pdf并下载
  13. 搜索引擎是如何工作的?
  14. Ormlite 介绍 一
  15. 376招募线上被试 | 你对“中文句子”的记忆情况如何?
  16. 更新网卡后蓝牙无法删除亦无法连接问题
  17. Python作业day2购物车
  18. 数字分割(拆数字)的两种方法
  19. 【计算机毕业设计】视频教学管理系统
  20. 服务器显卡芯片,Intel服务器独立显卡官方美图:单卡四芯原来如此

热门文章

  1. java 避免重定向_java – 避免循环重定向使用HttpClient 4.1.1
  2. python win32库与subprocess_python subprocess 模块使用(以及详解管道阻塞的坑)
  3. 简述div标签和span标签的不同_div与span的区别是什么?
  4. Vue:Vue项目中引入第三方库报错Unexpected token ‘<‘
  5. JavaScript:加载请求本地资源工具StaticResourceUtil.js
  6. HTML:表格、表单和rem
  7. 使用FileWriter和BufferedWriter向文本文件中写信息
  8. Tensorflow中训练得到Nan错误的分析
  9. 全局拉普拉斯平滑之(1)Strucutre extraction from texture via relative total variation及稀疏矩阵求解
  10. 趣闻|论文不必参考任何文献?看到作者,网友大呼失敬了