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

这篇具有很好参考价值的文章主要介绍了一文道破Java中的深拷贝,浅拷贝,零拷贝。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

一文道破Java中的深拷贝,浅拷贝,零拷贝,秋招总结&小白入坑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()方法实现了文件传输的零拷贝。数据直接从源文件通道传输到目标文件通道,而不需要先复制到应用程序的内存中。这种方法在处理大文件时可以提高性能并减少内存消耗。

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

一文道破Java中的深拷贝,浅拷贝,零拷贝,秋招总结&小白入坑Java,java,开发语言文章来源地址https://www.toymoban.com/news/detail-765032.html

到了这里,关于一文道破Java中的深拷贝,浅拷贝,零拷贝的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一文道破将bean注入到Spring中的几种方式

    前言: 前两天有学妹问我如何将bean注入到Spring中,虽问题较简单,但还是写此文以告之。 在Java的Spring框架中,将bean注入到容器中是核心概念之一,这是实现依赖注入的基础。Spring提供了多种方式来将bean注入到容器中。 写此文,同时也希望这篇文章能帮助到各位路过的大佬

    2024年04月15日
    浏览(44)
  • JS的深拷贝和浅拷贝

    ‍本文作者是360奇舞团开发工程师 在讨论深拷贝和浅拷贝之前,先来了解下Js基本数据和引用数据类型的存储问题 基本数据类型:Number String Boolean Undefined Symbol Null 引用类型 :Object,function,Array等 基本数据类型的值存放在栈中,在栈中存放的是对应的值;引用类型对应的值存

    2024年02月09日
    浏览(39)
  • Java中的深克隆和浅克隆(Clone)

    浅克隆(shallow clone)和深克隆(deep clone)是两种不同的对象复制方法。 浅克隆会创建一个新对象,然后将原始对象的所有字段复制到新对象中。如果字段是基本类型,则它们的值将被直接复制。如果字段是引用类型,则只会复制引用,而不会复制引用指向的对象。这意味着

    2024年02月16日
    浏览(39)
  • Java中的浅拷贝与深拷贝

    在Java中,对象的拷贝有两种方式:浅拷贝和深拷贝。它们分别代表了不同的拷贝方式,拷贝出的新对象与原始对象之间存在一定的差异。本文将详细介绍浅拷贝和深拷贝的概念、特点和实现方式,并且通过实例进行解析。  一、浅拷贝  浅拷贝是指在对一个对象进行拷贝时,

    2024年02月14日
    浏览(36)
  • Java中的集合及深拷贝与浅拷贝

    Java是一种面向对象的编程语言,其中集合是常用的数据结构之一,具有方便快捷的特点。在Java开发中,我们常常需要对集合进行复制(拷贝)操作。但是,拷贝操作并不是简单的复制,而应该分为浅拷贝和深拷贝两种不同的方式,本文将分别介绍Java中集合的浅拷贝和深拷贝

    2024年02月07日
    浏览(35)
  • 【算法专题】二叉树中的深搜(DFS)

    深度优先遍历(DFS,全称为 Depth First Traversal),是我们树或者图这样的数据结构中常用的⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分支,直到一条路径上的所有节点都被遍历完毕,然后再回溯到上一层,继续找⼀条路遍历。 在二叉树中,常见的深度优先遍历为

    2024年02月03日
    浏览(40)
  • 对java中的List进行深拷贝,并进行删除测试

    ListString list = new ArrayList();  // 需要拷贝的原始List list.add(\\\"aaa\\\"); list.add(\\\"bbb\\\"); list.add(\\\"ccc\\\"); ListString listNew = new ArrayList();  // 新List // 将原始List的值赋值给新List CollectionUtils.mergeArrayIntoCollection(new Object[list.size()], listNew); Collections.copy(listNew, list); // 现在将心List中的值删除一个,会

    2024年02月11日
    浏览(29)
  • 一文彻底理解python浅拷贝和深拷贝

    万物皆对象:在学习python的深浅拷贝之前我们必须要知道一个事情,就是python对象的引用,在python里面, 万物皆对象,万物皆对象,万物皆对象 ,不管什么数据类型都是对象。我们定义一个变量并给这个变量赋值的时候赋的并不是这个对象值,而是这个对象引用,并不是一

    2024年02月07日
    浏览(43)
  • 一文详解java中的==和equals()

    目录 一、\\\"==\\\"运算符 二、\\\"equals()\\\"方法 三、举例说明和解释 3.1、例子 3.2、基本数据类型的比较 3.3、引用数据类型的比较     3.3.1 String类     3.3.2 未重写equals方法的类 四、为什么重写equals方法就一定要重写hashCode方法  4.1 为什么要重写equals方法 4.2 hashCode 4.3 为什么equas和ha

    2024年02月04日
    浏览(64)
  • 一文搞懂Java中的容器(集合类)

    提示:本文介绍的集合类有很多,有的是日常开发常用的,有的是面试常问的,建议大家都了解一点。 Java 容器分为 Collection 和 Map 两大类,其下又有很多子类,如下所示: 这里有个面试点:Collection 和 Collections 有什么区别? Collection 是一个集合接口 Collections 是一个包装类,

    2024年02月09日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包