• Java 的基本类型与引用类型的深拷贝和浅拷贝


    数据分为基本数据类型引用数据类型

    基本数据类型的:数据直接存储在栈中
    引用数据类型的:栈中存储的是一个指针,指向堆中的一块内存,真实的数据存放在堆内存里

    对于一般拷贝操作而言,就是把中的数据拷贝一份,新数据和源数据一样

    基本类型

    所以,对于基本类型,由于数据直接存储在栈中,拷贝一份就意味着把数据拷贝了一份

    比如int x = 4,那么栈中就有一块内存储存了4int y = x就是在栈中新建一个变量(一块内存),并拷贝源数据,即4,所以此时栈中有两块内存储存的都是4,一个是x一个是y

    所以基本类型默认就是深拷贝

    那么,对于基本类型,怎么实现浅拷贝呢?C++在某种意义上实现可以通过指针或引用实现,而Java没有指针,所以并不太好实现,可以参考这里

    引用类型

    对于引用类型就不太一样了,string x = "hello"时,在栈中有一个变量x,指向堆内存中的hello

    string y = x时,复制栈中的数据,也就是说,yx指向同一块堆内存,这就是浅拷贝,所以java引用类型默认是浅拷贝

    深拷贝是要在栈中新建一个变量的同时,并且在堆中也新建一块内存,把要复制的值存进去,并将在栈中新建的变量指向堆中新建的内存

    即:
    浅拷贝:在栈中新建一个变量,还是指向同一块内存
    深拷贝:在栈中新建一个变量,并且在堆中也新建一块内存,把要复制的值存进去,将在栈中新建的变量指向堆中新建的内存

    那么,既然用=复制是浅拷贝,怎样能够实现深拷贝呢?

    对于数组,当然可以通过.clone()

    int[] src = ...
    int[] dest = src.clone();
    
    • 1
    • 2

    对于class,一种比较安全的方法是先序列化,然后反序列号,可以参考这里

    特殊的 String 类型

    Java中的String类型比较特殊,虽然他是引用类型,但是他具有不可变性,也就是说,在堆内存中的一块String,如"hello",内容是不能更改的

    string x = "hello"后,x="world"会在堆内存中重新划一块内存,储存"world",并将x指向新内存,原有内存后续如果没有被引用就会被清理掉

    然而,若我们string x = "hellostring y = x,y和x指向同一块堆内存"hello",但是如上一段所说,x="world"会在堆中新建一块内存,而不是更改原有内存的数据,也就是说,现在,x指向world,而y依然指向hello

    所以对String虽然是引用类型,但是直接使用=等号,是深拷贝

    更详细的证明见这里

  • 相关阅读:
    LabVIEW什么时候需要使用DLL封装 Calling External APIs
    分布式运用之企业级日志ELFK+logstash的过滤模块
    AI技术崛起:数据可视化之路更近
    RHCE第六次作业
    如何快速看懂复杂代码
    Java实现拼图小游戏(4)—— 打乱图片(含二维数组知识点)
    python中pytorch的广播机制——Broadcasting
    Netty(二)- NIO三大组件之Buffer
    【JUC】循环屏障CyclicBarrier详解
    【WinForm详细教程八】WinForm中的TreeView控件
  • 原文地址:https://blog.csdn.net/qq_37454669/article/details/126142355