一文道破Java中的深拷贝,浅拷贝,零拷贝

前言

在Java编写代码中,对象的拷贝是一个常见的操作。根据拷贝的层次和方式不同,可以分为深拷贝、浅拷贝和零拷贝。本篇文章我们将详细介绍这三种拷贝方式的概念、实现方法以及使用场景,方便大佬学习及面试。

在这里插入图片描述

深拷贝

深拷贝是一种创建对象副本的方法,其中新对象与原始对象完全独立。这就意味着新对象的所有字段都被复制,并且如果字段是引用类型,那么递归地执行深拷贝,以确保新对象和原始对象不共享任何内部对象。

如何实现深拷贝呢,接下来介绍一下:

  1. 手动实现:通过创建一个新的对象,并逐个复制字段的值。如果字段是引用类型,需要递归地创建该字段的新实例,只不过这个过程比较繁琐。
  2. 使用序列化:将对象序列化为字节流,然后再反序列化回一个新对象。这种方法要求对象及其所有组成部分都是可序列化的。
  3. 使用克隆:实现Cloneable接口并重写clone()方法。但这种方法有争议,因为它可能不提供真正的深拷贝,除非所有相关的类都正确实现了clone()方法。

举个栗子,我们现在有简单的Person类和一个Address类:

class Address implements Serializable {  private String street;  // ... 其他属性和方法 ...  
}  class Person implements Serializable {  private String name;  private Address address;  // ... 其他属性和方法 ...  public Person deepCopy() {  try {  // 使用序列化实现深拷贝  ByteArrayOutputStream baos = new ByteArrayOutputStream();  ObjectOutputStream oos = new ObjectOutputStream(baos);  oos.writeObject(this);  oos.close();  ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());  ObjectInputStream ois = new ObjectInputStream(bais);  return (Person) ois.readObject();  } catch (Exception e) {  throw new RuntimeException(e);  }  }  
}

代码解释:
不难看出,Person类有一个Address类型的字段。我们实现Serializable接口了并使用序列化和反序列化技术,可以创建一个Person对象的深拷贝。这就意味着新创建的Person对象和原始对象是完全独立的,它们不共享任何内部状态。

浅拷贝

浅拷贝创建一个新对象,并复制原始对象的所有非静态字段到新对象。但是,如果字段是引用类型,那么只复制引用而不复制引用的对象。因此,对于引用类型的字段,原始对象和新对象共享同一个内部对象。

那么实现浅拷贝呢,方法如下:

我们通常可以通过创建一个新对象,并且使用构造函数或setter方法将原始对象的值复制到新对象中来实现浅拷贝。Java中的自动装箱和拆箱机制可以简化基本数据类型的复制

Such as:

使用上面的Person和Address类为例:

class Person {  private String name;  private Address address;  // ... 其他属性和方法 ...  public Person shallowCopy() {  Person copy = new Person();  copy.setName(this.name); // 复制基本数据类型字段  copy.setAddress(this.address); // 只复制引用,不复制引用的对象  return copy;  }  
}

对上面的代码解释一下:
我们创建了一个新的Person对象并且复制基本数据类型字段的值和引用类型字段的引用来实现浅拷贝。这意味着修改新对象的name字段不会影响原始对象,但修改新对象的address字段会影响原始对象,因为它们共享同一个Address对象。

零拷贝

零拷贝是一种在数据传输过程中避免不必要的数据复制的技术。零拷贝通常与I/O操作相关,尤其是当数据从一个存储位置移动到另一个存储位置时。通过直接在内存、文件或网络之间传输数据,零拷贝技术可以减少CPU的使用和内存带宽的消耗,从而提高性能。

Java中什么地方用到了零拷贝技术呢?比如:

  • MappedByteBuffer:使用内存映射文件将文件或文件的一部分映射到内存中,从而允许直接访问文件数据而不需要将数据复制到应用程序的内存中。这可以通过FileChannel中的map()方法实现。
  • FileChannel的transferTo/transferFrom方法:这些方法允许数据直接在文件通道或套接字通道之间传输,而不需要先复制到应用程序的内存中。比如,可以使用FileChannel中的transferTo()方法将数据直接从文件发送到网络套接字。
  • DirectBuffer:通过使用直接缓冲区(DirectBuffer),数据可以直接在操作系统的原生内存中进行处理,而不需要先复制到Java堆内存中。这可以通过创建一个ByteBuffer并调用其allocateDirect()方法来实现。

如,上面就是Java的NIO库提供了一些零拷贝技术的实现方法。

try (FileChannel sourceChannel = new FileInputStream("source.txt").getChannel();  FileChannel destinationChannel = new FileOutputStream("destination.txt").getChannel()) {  destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size());  
} catch (IOException e) {  e.printStackTrace();  
}

我们在上面的代码中就使用FileChannel的transferFrom()方法实现了文件传输的零拷贝。数据直接从源文件通道传输到目标文件通道,而不需要先复制到应用程序的内存中。这种方法在处理大文件时可以提高性能并减少内存消耗。

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关键词热度分析工具_谷歌SEO推广排名的关键要素(一)利用谷歌关键词分析工具分析关键词...

大家好,我是谷歌鸿飞,到今年算起,从业谷歌SEO,已经十一个年头了。服务过的外贸企业也有几百家,接触和操作过外贸产品也有上千种。这么多的企业,这么多的产品,思绪万千,不知如何下笔。…

计算机桌面设置定时,如何设置可以每月自动变化的日历桌面?

设置步骤:1、显示电脑桌面(即把所有窗口都最小化);2、Windows Xp和Windows 2000设置有些不同:(windows vista好像不能设置活动桌面)Windows xp:在电脑桌面点击鼠标右键,出现菜单,选择“属性”,然…

系统辨识理论及应用_控制理论学习书单推荐(值得一读)

经 System control 授权,基于控制理论学习书单整理改编。提起系统与控制领域的学习,经常被谈论到的就是,对于刚接触这个领域的初学者总会在各种控制理论中迷茫,有的甚至直接劝退。面对众多理论,完全无从下手。下面就简…

重庆电子工程学院计算机专业,重庆计算机电子工程职业学院2020年招生录取分数线...

重庆计算机电子工程职业学院2020年录取分数线暂未公布,预计在2020年6月份公布。以往数据表明高职院校的录取分数线和当年的高考题目难易程度有关,考生可参考重庆计算机电子工程职业学院历年来院校录取分数线情况。重庆计算机电子工程职业学院录取分数线招…

上海交通大学计算机应用基础答案,西安交通大学17年3月课程考试《计算机应用基础》作业考核试题答案...

http://www.mouxue.com/forum.php? ... p;page1#pid1402268一、单选题(共 30 道试题,共 60 分。)V 1. 在Wor中,要选定全文,可用的快捷键为()。. trlS. trlV. trl. trl标准答案:2. Winows XP 任务栏不能设置为()。. 自动隐藏. 时…

正则只能小于0负数_2019–2020学年七年级数学期末考试考点之正数与负数考点详解...

七年级数学期末考试第一讲之正数与负数考点详解嗨,大家好,这里是摆渡学涯。马上我们就要迎来期末考试了,你们有没有开始复习呢?这次课程咱们来为大家讲一下数的考点,教你轻松学数学。数的概念数从是否为正负数的角度来…

HTML可以替代CSS的所有功能,CSS-用Divs替换HTML表

CSS-用Divs替换HTML表好吧,我试图接受这样的想法,即不应使用html表,而应使用div。 但是,我经常有类似于以下内容的代码First Name:Last Name:Address:NYCAUSACAN我希望标签对齐并且我希望控件对齐。 不使用表格怎么办?…

controller接收json数据_SpringMVC实现多种数据类型绑定

点击上方“放学等我”,选择“置顶公众号”精品文章,第一时间送达绑定基本数据类型Java基本数据类型int的默认值是0,在使用int进行url传递参数时,参数key是必须写的,其值也只能是int类型的,否则将会报错。 比…

初中学历在辽宁学计算机,在辽宁省实验中学学习是怎样一番体验?

本人姓名:韩杨泰衍。辽宁省实验中学2012届毕业生,2012年高考考入清华大学。第一次在知乎上写回答,有言语不当之处还请各位看官见谅。体验之一:学习上不断积累与释放的自卑感,伴随着不断获得和失去的荣誉。我2009年中考…

宝塔设置thinkphp的伪静态_宝塔面板与WDCP狭路相逢,谁才是国产之光?

我本来想给大家写一篇工具类的杂谈,思来想去又想到了可视化面板,就目前国产面板而言,WDCP、宝塔面板、AMH等,说是群雄逐鹿一点都不为过,AMH4.2之后,可以说是走了相当一部分人,暗示收费版本&…

计算机桌面打标签,在电脑桌面上添加便签的方法步骤详解(2)

电脑的桌面便签软件推荐1、CintaNotes电脑的桌面便签软件推荐图1CintaNotes是一款非常轻巧实用的笔记软件,可看作EverNote轻量级替代品。CintaNotes只需1个exe,体积仅1MB,却拥有EverNote易于收集、实时搜索、条状排列、tag分类的优点,更有EverNote 所不具备的中文搜索、纯文本更…

windows。forms.timer设置第一次不等待_适用于初学者的中线交易策略——金叉的三种设置条件...

本文将介绍了使用移动平均线最重要的方法之一——金叉。我们将描述该信号的产生条件,然后深入探讨一下三个交易案例。什么是金叉?当短期移动平均线与长期移动平均线相交时,黄叉就会产生。听起来确实很简单。然而,关键是构成交叉的移动平均线…

html如何做卷展菜单,3DMax“对象属性”卷展栏如何操作?有啥秘诀呢?

“动画”菜单 “骨骼工具”“骨骼工具”浮动框 “对象属性”卷展栏。使用骨骼“对象属性”卷展栏上的控件可以将其他对象转变为骨骼。这些控件还可以控制骨骼的刚性及对齐方式。注意使用“重置缩放”选项可以重置骨骼的缩放。1、启用/禁用骨骼启用此选项后,选定骨骼…

python多线程写同一个文件_Python多线程快速写入文件,python,飞速

Python多线程快速写入文件,python,飞速 发表时间:2020-07-10 乱序多线程写入 举个最简单的例子,只要求快速写入即可,对顺序无要求时: import threading def write_string(string, path"test.csv"): with open(path, a) …

2021山东科技大学计算机学院,2021年3月山东科技大学计算机等级考试报名工作通知...

【导语】2021年3月山东科技大学计算机等级考试报名工作通知已公布,为了方便广大考生的查阅,下面无忧考网为您详细介绍一下本次计算机等级考试报名的具体事宜,希望广大考生及时关注,如有相关疑问,敬请关注无忧考网为您实…

怎么查看电脑有没有python_python人工智能爬虫系列:怎么查看python版本_电脑计算机编程入门教程自学...

本文由简码编程原创,保留所有版权,转载请注明出处。 本python人工智能爬虫系列教程基于Python3.0版本, 将python结合windows桌面开发工具aardio一起做可视化的开发, 用python做逻辑处理,用aardio做窗口界面, 不用再看着黑黑的python命令行窗口, 有window…

html表头的标签,HTML 表头单元格标签

HTML 标签标签定义及使用说明 标签定义 HTML 表格中的表头单元格。HTML 表格有两种单元格类型:表头单元格 - 包含头部信息(由 元素创建)标准单元格 - 包含数据(由 元素创建) 元素中的文本通常呈现为粗体并且居中。 元素中的文本通常是普通的左对齐文本。浏览器支持…

python3安装pymysql_python安装PyMySQL

官网操作教程:http://www.runoob.com/python3/python3-mysql.html 1、简介 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。 PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客…

计算机控制系统课程设计中期报告,课程设计中期报告模板.doc

课程设计中期报告模板概要新疆大学信息科学与工程学院《程序设计》课程设计中期报告题目:专 业 计算机科学与技术学 生 姓 名学 号联 系 方 式班 级 计算机15-班组 员 姓 名联 系 方 式检 查 日 期 2016.7.29新疆大学信息科学与工程学院目 录1. 课程设计内容概述11.…

python中计算如何实现_基于python如何实现计算两组数据P值

我们在做A/B试验评估的时候需要借助p_value,这篇文章记录如何利用python计算两组数据的显著性。 一、代码# TTest.py # -*- coding: utf-8 -*-# Created on 2020-05-20 20:36 # TTest.py # author: huiwenhua## Import the packages import numpy as np from scipy import stat…