JAVA 浅拷贝和深拷贝

article/2025/10/5 14:26:06

拷贝

拷贝即对已有的数据创建一个副本,在 Java 中,拷贝可分为引用拷贝、浅拷贝、深拷贝。

引用拷贝

在 Java 中,实例化后的对象存储在堆区,而局部变量存放在局部变量表(栈)中,如:

public void yinYongCopy() { User user = new User("xiaoming", 12); 
}

user 变量只是存放堆区 User 实例的引用(地址)。那么把 user 赋值另一个变量 copy,称为引用拷贝(相当于地址赋值)。

public void yinYongCopy() { User user = new User("xiaoming", 12); User copy = user; 
}

user 和 copy 两个变量存放了 User 实例的指向,他们指向了同一份堆内存空间。

浅拷贝

在 java 中,默认的拷贝指的是类重写 Object 类中的 clone 方法,调用该方法进行拷贝。Object 类中的 clone 方法使用 Native 修饰,由本地方法实现,对于类型只是做引用拷贝。

public class User implements Cloneable {private String name;private Integer age;private Animal animal;get...set...@Overrideprotected User clone() throws CloneNotSupportedException {return (User) super.clone();}
}public class Animal implements Cloneable {private String name;private Integer age;get..set..@Overrideprotected Animal clone() throws CloneNotSupportedException {return (Animal) super.clone();}
}public class Copy {public static void main(String[] args) throws CloneNotSupportedException {User user = new User();user.setAge(10);user.setName("xiaoming");user.setAnimal(new Animal("wangcai", 10));System.out.println(user);User clone = user.clone();System.out.println(clone);System.out.println(user == clone);System.out.println(user.getAnimal() == clone.getAnimal());}
}

使用 clone 方法生生成新的对象,此时在堆中产生新的对象,clone 存放了该对象的引用。但是需要注意,此时 user 和 copy 中的 animal 指向堆空间中同一个实例,即只是做了引用的拷贝。

深拷贝

深拷贝相对于浅拷贝而言,会对所有数据类型都进行拷贝一份,包括这个对象所包含的内部对象。java 中上实现深拷贝的方式有两种:

  • 对浅拷贝进行加强,对象中引用属性进行 clone 操作;
  • 通过序列化;
  • 借助三方工具类;

浅拷贝加强

对浅拷贝进行加强,对象中引用属性进行 clone 操作,以下例子 User 类 clone 的时候也对 animal 进行拷贝。

public class User implements Cloneable {private String name;private Integer age;private Animal animal;get..set...@Overrideprotected User clone() throws CloneNotSupportedException {User clone = (User) super.clone();clone.setAnimal(animal.clone());return clone;}
}public class Copy {public static void main(String[] args) throws CloneNotSupportedException {User user = new User();user.setAge(10);user.setName("xiaoming");user.setAnimal(new Animal("wangcai", 10));System.out.println(user);User clone = user.clone();System.out.println(clone);System.out.println(user == clone);System.out.println(user.getAnimal() == clone.getAnimal());}
}

序列化

User 类实现 Serializable 接口,对堆区中的实例进行读写,从而实现对实例的全部拷贝。

public class User implements Serializable, Cloneable {private String name;private Integer age;private Animal animal;get...set...@Overrideprotected User clone() {try {ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);oos.flush();ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));return (User) ois.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();return null;}}
}

借助三方工具类

例如使用 fastJson 工具对对象实现深度拷贝。

@Override
protected User clone() {String s = JSON.toJSONString(this);return JSON.parseObject(s, User.class);
}


http://chatgpt.dhexx.cn/article/AG4JO6R6.shtml

相关文章

js浅拷贝和深拷贝

1、JS数据类型 基本数据类型:Boolean、String、Number、null、undefined 引用数据类型:Object、Array、Function、RegExp、Date等 2、深拷贝与浅拷贝 深拷贝和浅拷贝都只针对引用数据类型, 浅拷贝会对对象逐个成员依次拷贝,但…

C++浅拷贝和深拷贝

1、浅拷贝 浅拷贝:又称值拷贝,将源对象的值拷贝到目标对象中去,本质上来说源对象和目标对象共用一份实体,只是所引用的变量名不同,地址其实还是相同的。 举个简单的例子,你的小名叫西西,大名叫…

彻底理解Python中浅拷贝和深拷贝的区别

目录 前言 1. 浅拷贝和深拷贝的概念 2. is和的区别 3. 赋值操作 4. copy模块里面的copy()方法 5. copy模块里面的deepcopy()方法 6.字典自带的copy方法 7.切片表达式拷贝 8.总结 前言 Python 的所有变量其实都是指向内存中的对象的一个指针,这确实和之前学…

如何理解java的回调函数?

对于技术问题,会用是一回事,理解这个技术问题的来龙去脉、设计者当初为什么要设计这个功能、这个技术问题有哪些优势、适用哪些场景又是另外回事了。 前者照猫画虎得其形,后者形神兼备得其意,这也是所谓青铜与王者的区别。 会使…

java使用回调函数

java回调函数 回调函数(callback Function),顾名思义就是用来回调的函数。在两个类A、B中,A在调用B接口的同时B也在调用A 回调函数也常用于线程中的异步获取消息。 举个简单的例子,公司中老板分发任务给员工A&#…

java中回调函数的实现

在java的事务中,有时候可能会遇到以下情况,第一步是更新某某表,中间可能要更新不确定的多步,最后一步是更新缓存,结构大致如下: (1)updateA(); (2)updateXX…

什么是java回调函数

回调函数 一:故事背景二:概念三:回调函数的作用四:java中如何进行回调4.1 类图4.2 定义回调接口4.3 实现回调接口4.4 调用方法使用回调函数4.5 Main函数调用4.6 总结描述 五:回调函数的优点5.1 灵活性5.2 解耦性5.3 异…

简单举例JAVA回调函数的实现

来自维基百科的对回调(Callback)的解释:In computer programming, a callback is any executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time. This execut…

java回调函数机制

Java回调函数机制 参考了网上的一些资料,下面也做出一些总结,供初学者了解学习。 一、 概述 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调、异步调用 。 同步调用:一…

java中如何实现回调函数

最近工作需要研究了一会别人写的库,其中充满着各种"回调函数",因此把自己理解给记录下来,存档。 首先我们来看看回调函数 这个概念的具体由来,百度百科的示义如下: 回调函数就是一个通过函数指针调用的函数。…

Java回调函数 + 使用案例

文章目录 前言什么是回调函数第0个版本第1个版本第2个版本第3个版本第4个版本第5个版本第6个版本回头解析前言描述的问题1. MethodIntrospector.selectMethods()2. 抽象类MethodIntrospector3. 方法selectMethods()4. 成员变量USER_DECLARED_METHODS5. 方法doWithMethods()6. d…

Java-回调函数

什么是回调 函数调用可以分为三种模式,串行调用、异步调用、回调。这三种都是日常开发中常见到的方式。 一个方法执行完,再执行下一个,串行逻辑会阻塞线程执行流程,等到所有逻辑执行结束,线程才会结束。 异步执行是…

java回调函数(callBack)

最近有个新同事给我写了个接口,说是用到了回调,我等了半天发现结果才返回回来,把我都整急了。最后我看了他的代码,目瞪口呆。他还信誓旦旦的说没错,按网上的例子来写的。 我一搜,网上例子真一大堆&#xff…

java回调函数的作用以及运用

模块之间总是存在这一定的接口,从调用方式上看,可以分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,也是我们在写程序中经常使用的;回调是一种双向的调用模式,也就是说,被调用的…

Java回调函数理解和应用

#Java回调函数理解和应用 所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法,这样子说你是不是有点晕晕的。 在未理解之前,我也是一脸懵逼,等我理解之后&…

java回调函数(全干货)

产生接口回调的场景 产生接口回调的场景很简单,比如A叫B帮忙做一件事,交代完后A去忙别的事,然后B做完这件事之后会通知A, 通知A的这个动作就是接口回调的动作。接口回调 接口回调的意义是通过接口来实现解耦的的前提下调用另一个类的方法,也就是B为A准…

深入理解Java回调函数

废话不多说,像许多网上介绍回调机制的文章一样,我这里也以一个现实的例子开头:假设你公司的总经理出差前需要你帮他办件事情,这件事情你需要花些时间去做,这时候总经理肯定不能守着你做完再出差吧,于是就他…

java 回调函数解读

模块间调用 在一个应用系统中,无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种: (1)同步调用 同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b()&…

java中的回调函数

CALLBACK,即回调函数,是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接…

Java回调函数详解

什么是回调函数(CallBack) 在编写程序时,有时候会调用许多API中实现实现的函数,但某些方法需要我们传入一个方法,以便在需要的时候调用我们传入进去的函数。这个被传入的函数称为回调函数(Callback functi…