点击上方蓝色“方志朋”,选择“设为星标”

回复“666”获取独家整理的学习资料!


一、前言

拷贝这个词想必大家都很熟悉,在工作中经常需要拷贝一份文件作为副本。拷贝的好处也很明显,相较于新建来说,可以节省很大的工作量。在Java中,同样存在拷贝这个概念,拷贝的意义也是可以节省创建对象的开销。

Object类中有一个方法clone(),具体方法如下:

protected native Object clone() throws CloneNotSupportedException;
  1. 该方法由 protected 修饰,java中所有类默认是继承Object类的,重载后的clone()方法为了保证其他类都可以正常调用,修饰符需要改成public

  2. 该方法是一个native方法,被native修饰的方法实际上是由非Java代码实现的,效率要高于普通的java方法。

  3. 该方法的返回值是Object对象,因此我们需要强转成我们需要的类型。

  4. 该方法抛出了一个CloneNotSupportedException异常,意思就是不支持拷贝,需要我们实现Cloneable接口来标记,这个类支持拷贝。

为了演示方便,我们新建两个实体类DeptUser,其中User依赖了Dept,实体类代码如下:

Dept

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {private int deptNo;private String name;
}

User

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private int age;private String name;private Dept dept;
}

二、浅拷贝

对于基本类型的的属性,浅拷贝会将属性值复制给新的对象,而对于引用类型的属性,浅拷贝会将引用复制给新的对象。而像StringInteger这些引用类型,都是不可变的,拷贝的时候会创建一份新的内存空间来存放值,并且将新的引用指向新的内存空间。不可变类型是特殊的引用类型,我们姑且认为这些被final标记的引用类型也是复制值。

浅拷贝功能实现

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Cloneable{private int age;private String name;private Dept dept;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

如何验证我们的结论呢?首先对比被拷贝出的对象和原对象是否相等,不等则说明是新拷贝出的一个对象。其次修改拷贝出对象的基本类型属性,如果原对象的此属性发生了修改,则说明基本类型的属性是同一个,最后修改拷贝出对象的引用类型对象即Dept属性,如果原对象的此属性发生了改变,则说明引用类型的属性是同一个。清楚测试原理后,我们写一段测试代码来验证我们的结论。

public static void main(String[] args) throws Exception{Dept dept = new Dept(12, "市场部");User user = new User(18, "Java旅途", dept);User user1 = (User)user.clone();System.out.println(user == user1);System.out.println();user1.setAge(20);System.out.println(user);System.out.println(user1);System.out.println();dept.setName("研发部");System.out.println(user);System.out.println(user1);
}

上面代码的运行结果如下

falseUser{age=18, name='Java', dept=Dept{deptNo=12, name='市场部'}}
User{age=20, name='Java', dept=Dept{deptNo=12, name='市场部'}}User{age=18, name='Java', dept=Dept{deptNo=12, name='研发部'}}
User{age=20, name='Java', dept=Dept{deptNo=12, name='研发部'}}

三、深拷贝

相较于浅拷贝而言,深拷贝除了会将基本类型的属性复制外,还会将引用类型的属性也会复制。

深拷贝功能实现

在拷贝user的时候,同时将user中的dept属性进行拷贝。

dept类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept implements Cloneable {private int deptNo;private String name;@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}
}

user类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Cloneable{private int age;private String name;private Dept dept;@Overrideprotected Object clone() throws CloneNotSupportedException {User user = (User) super.clone();user.dept =(Dept) dept.clone();return user;}
}

使用浅拷贝的测试代码继续测试,运行结果如下:

falseUser{age=18, name='Java旅途', dept=Dept{deptNo=12, name='市场部'}}
User{age=20, name='Java旅途', dept=Dept{deptNo=12, name='市场部'}}User{age=18, name='Java旅途', dept=Dept{deptNo=12, name='研发部'}}
User{age=20, name='Java旅途', dept=Dept{deptNo=12, name='市场部'}}

除此之外,还可以利用反序列化实现深拷贝,先将对象序列化成字节流,然后再将字节流序列化成对象,这样就会产生一个新的对象。

热门内容:
  • 给IDEA换个酷炫的主题,这个有点哇塞啊!

  • 万字详解本地缓存之王 Caffeine

  • Java微服务 vs Go微服务,究竟谁更强!?

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡

Java中的深浅拷贝问题你清楚吗?相关推荐

  1. 浅谈关于java中的深浅拷贝

    一.浅拷贝(shallow copy) 1.如何实现浅拷贝? Object类 是所有类的直接或间接父类,Object中存在clone方法,如下 protected native Object clon ...

  2. java中的深浅拷贝

    https://blog.csdn.net/QLH04_04/article/details/89849812 转载于:https://www.cnblogs.com/wangjing666/p/11 ...

  3. java中的io复用_从 Java 中的零拷贝到五种IO模型

    在之前的文章中,我们聊过了 Java 中的零拷贝,零拷贝就是指数据不会在内核空间和用户空间之间相互拷贝.这样就减少了内核态与用户态的切换,自然就很高效. 拷贝文件只是 IO 操作中一个特殊的情况,大多 ...

  4. php深浅拷贝,JavaScript 中的深浅拷贝

    工作中经常会遇到需要复制 JavaScript 数据的时候,遇到 bug 时实在令人头疼:面试中也经常会被问到如何实现一个数据的深浅拷贝,但是你对其中的原理清晰吗?一起来看一下吧! 一.为什么会有深浅 ...

  5. JS(JavaScript)中实现深浅拷贝的几种方式(详细阅读 非常重要)。

    在了解深浅拷贝之前,我们先一起来简单来了解一下,JavaScript 数据存储的方式,以及数据类型(). JavaScript 中数据存储分为 简单数据类型和复杂数据类型(引用数据类型) 其中 5 种 ...

  6. java中的深浅克隆

    假设有一个对象object,在某处又需要一个跟object一样的实例object2,强调的是object和object2是两个独立的实例,只是在开始的时候,他们是具有相同状态的(属性字段的值都相同). ...

  7. python中的深浅拷贝

    1.    浅拷贝  copy.copy 浅拷贝是对于⼀个对象的顶层拷贝 通俗的理解是:拷贝了引⽤,并没有拷贝内容 浅拷贝只复制第一层数据,更深层的引用不管. 2.    深拷贝   copy.dee ...

  8. python中的深浅拷贝的区别

    li = [1,1,2,3,4,5,6,7,8,9]l2=li # 这样定义不行共用内存空间,其实是一体# l2 = [1,1,2,3,4,5,6,7,8,9]l3=li[:]for i in l2: ...

  9. python的深浅拷贝与linux中的软硬链接

    记录一下我对python的深浅拷贝以及linux中的软硬链接的理解 放在开头 软硬连接 python中对象的深浅拷贝 浅拷贝 深拷贝 copy.copy()对可变和不可变对象的不同 总结 放在开头 在 ...

最新文章

  1. 利用ashx和ajax实现表格的异步填充
  2. JVM-07垃圾收集Garbage Collection【GC日志分析】
  3. VMware 报错“Intel VT-x处于禁止状态”
  4. CBOW模型正向传播、矩阵乘积层实现
  5. 封装好的实用的读写XML类---增删改查XML
  6. 测量两台机器的的网络延迟和时间差
  7. VS2015中搭建lua环境
  8. [ZZ] GTX760首测
  9. 海康SDK设备信息NET_DVR_GET_DEVICECFG解析
  10. linux dstat 多 cpu,dstat 用法总结
  11. 混淆电路(Garbled Circuit)
  12. 跑PIN码破解无线网络WIFI密码的原理分析(转)
  13. 整合UWALOHA和VBF
  14. Python周刊491期
  15. dnf史诗计算机手机版,dnf计算器装备模拟100手机版
  16. Vue 实现拖拽模块(二)自定义拖拽组件位置
  17. acr38u PHP调用,ACS ACR38U-N1智能卡读卡器驱动
  18. VMware虚拟机安装CentOS7,登录时,输入密码出现抱歉,没有奏效,请再试一遍。解决方法:
  19. 老卫带你拿offer---招银网络科技篇
  20. 昆仑通态mcgs通过西门子200PLC200smart通讯

热门文章

  1. python中根据URL获得数据库的名称及IP
  2. 2018-3-10 kKNN与K-mean的区别以及各自的Python代码(别人写的好的文章)
  3. hexo博客更新主题后上传Git操作
  4. Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)
  5. 我的路子 - 发现游戏为模型的软件架构方式
  6. Autocomplete 自动补全(Webform实战篇)
  7. HTTP请求报文和HTTP响应报文(转)
  8. AutoConfig工具使用
  9. 鸽巢原理(The Pigeonhole Principle)(抽屉原理)
  10. 如何建立和维护自己的“人脉”