Clone方法与浅拷贝&深拷贝

  • 介绍
  • 如何实现
  • 浅拷贝 shallow copy
  • 深拷贝 deep copy
  • 数组中的clone

介绍

在Java中,如果需要创建一个对象的副本,特别是这个对象的创建需要很大代价时,可以使用Clone()方法快速高效创建对象副本。

如何实现

实现Cloneable接口,重写Object.clone()方法即可。

class OracleDriver implements Cloneable{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic OracleDriver clone() throws CloneNotSupportedException {return (OracleDriver) super.clone();}
}

通常来说,clone之后的对象与原生对象应该是相互独立的,没有任何关联的,为了使原生对象与克隆对象保持独立,需要视不同情况使用浅拷贝与深拷贝。

当类中包含可变对象时,如果使用浅拷贝,就会发生以下情况:

class OtherInfo{private String name;/* getter & setter*/@Overridepublic String toString() {return "hashCode= {" + hashCode() + "}OtherInfo{" +"name='" + name + '\'' +'}';}
}class OracleDriver implements Cloneable{private String name;private OtherInfo otherInfo;public OracleDriver(OtherInfo otherInfo){this.otherInfo = otherInfo;}/* getter & setter*/@Overridepublic OracleDriver clone() throws CloneNotSupportedException {return (OracleDriver) super.clone();}@Overridepublic String toString() {return "hashCode= {" + hashCode() + "}OracleDriver{" +"name='" + name + '\'' +", otherInfo=" + otherInfo +'}';}
}public static void main(String[] args) throws CloneNotSupportedException {OracleDriver origin = new OracleDriver(new OtherInfo());OracleDriver clone = origin.clone();System.out.println("origin:" + origin);System.out.println("clone:" + clone);}/*打印结果:origin:hashCode= {1175962212}OracleDriver{name='null', otherInfo=hashCode= {918221580}OtherInfo{name='null'}}clone:hashCode= {2055281021}OracleDriver{name='null', otherInfo=hashCode= {918221580}OtherInfo{name='null'}}*/

结果

可以看到原生对象与克隆对象引用的OtherInfo的hashCode是一致的,也就是引用的是同一个实例对象,这种情况下,原生对象与克隆对象是存在关联的,当原生对象修改了OtherInfo对象时,克隆对象也被修改了,这样是不行的。这时候需要深拷贝。

浅拷贝 shallow copy

当一个类中的成员变量只包含8中原生数据类型或者是不可变数据类型的变量时,只需要当前类实现Cloneable接口即可。

class OracleDriver implements Cloneable{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic OracleDriver clone() throws CloneNotSupportedException {return (OracleDriver) super.clone();}
}

深拷贝 deep copy

当一个类中的成员变量存在可变数据类型的变量时,比如引用了另一个类,为了保持原生对象与克隆对象相互独立,需要在clone()方法返回之前,修改这些可变对象,通常会clone这些可变对象,并使用克隆对象替换这些可变对象。

OracleDriver引用了OtherInfo

class OracleDriver implements Cloneable{private String name;private OtherInfo otherInfo;public OracleDriver(OtherInfo otherInfo){this.otherInfo = otherInfo;}@Overridepublic OracleDriver clone() throws CloneNotSupportedException {OracleDriver oracleDriver = (OracleDriver) super.clone();OtherInfo otherInfo = oracleDriver.getOtherInfo().clone();oracleDriver.setOtherInfo(otherInfo);return oracleDriver;}@Overridepublic String toString() {return "hashCode= {" + hashCode() + "}OracleDriver{" +"name='" + name + '\'' +", otherInfo=" + otherInfo +'}';}

引用类也需要实现Cloneable接口

class OtherInfo implements Cloneable{private String name;@Overrideprotected OtherInfo clone() throws CloneNotSupportedException {return (OtherInfo) super.clone();}@Overridepublic String toString() {return "hashCode= {" + hashCode() + "}OtherInfo{" +"name='" + name + '\'' +'}';}
}

结果

可以看到原生对象与克隆对象应用的OtherInfo是两个实例,原生对象与克隆对象彼此不影响。

public static void main(String[] args) throws CloneNotSupportedException {OracleDriver origin = new OracleDriver(new OtherInfo());OracleDriver clone = origin.clone();System.out.println("origin:" + origin);System.out.println("clone:" + clone);
}
/*
打印结果:
origin:hashCode= {1175962212}OracleDriver{name='null', otherInfo=hashCode= {918221580}OtherInfo{name='null'}}
clone:hashCode= {2055281021}OracleDriver{name='null', otherInfo=hashCode= {1554547125}OtherInfo{name='null'}}
*/

数组中的clone

在Java中,数组对象已经原生实现了Cloneable接口,但实现的是浅拷贝。所以当数组中存在可变对象时,需要自行替换掉这些可变对象。

Clone方法与浅拷贝深拷贝相关推荐

  1. 详解Java中的clone方法 -- 深拷贝和浅拷贝

    Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...

  2. 详解Java中的clone方法 -- 原型模式

    Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...

  3. 对象的克隆(clone方法)

    1.深拷贝与浅拷贝 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象.深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象. 2.深拷贝和浅拷贝的 ...

  4. Java基础篇:对象拷贝:clone方法 以及 序列化

    我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...

  5. 关于Java的Object.clone()方法与对象的深浅拷贝,java面试题,java初级笔试题

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...

  6. Java基础深度总结:Object类-clone方法

    凡心所向,素履所往,生如逆旅,一苇以航. 内容 1.clone概述 2.Cloneable接口 3.clone与new的区别 4.浅拷贝与深拷贝(重点) 5.Object.clone 6.浅拷贝存在的 ...

  7. java cloneable_java开发——Cloneable接口、clone()方法和深浅拷贝

    1.实现Cloneable接口表明该类的对象是允许克隆的. 2.允许克隆的意思是:可以调用clone()方法. 3.深拷贝还是浅拷贝,取决于如何重写Object的clone()方法. 4.原对象和克隆 ...

  8. java中clone方法的理解(深拷贝、浅拷贝)

    文章目录 前言: 知识点一:什么是浅拷贝? 知识点二:什么是深拷贝? 知识点三.java拷贝(clone)的前提: 知识点四:浅拷贝案例: 拷贝类: 测试类: 总结: 下面通过画图示意: 知识点五:深 ...

  9. 【java】克隆(clone),浅拷贝和深拷贝的区别

    前言 在很多人初学的时候,一定会被克隆是什么?怎么使用克隆?浅拷贝和深拷贝又是啥?所搞得晕头转向.这里我希望用最简单的语言向大家介绍我自己的理解.(我们马克思老师说,你能不能用农民也听得懂的语言介绍一 ...

最新文章

  1. STM32:Flash擦除与读写操作(HAL库)
  2. 阶乘与斐波那契数的理解
  3. AAAI2021论文合集汇总!(持续更新)
  4. 每周一荐:foobar2000, 奇幻人生, 一个Flash小游戏
  5. java byte md5_Java开发网 - byte[]按自定义编码转换成String(MD5)
  6. List、Map、Set之间的联系与区别:
  7. 绿色iPhone 13和紫色iPad Air将在明天发布?网友:苹果又寻思在配色上“整活儿”...
  8. 【Flink】Flink 上海会议 【视频笔记】
  9. webrtc系列3——对于stun和turn的理解
  10. 计算机基础a3知识点,《计算机应用基础》期末试卷A(A3版).doc
  11. 8086中寻址方式详解
  12. 使用Android Studio和阿里云数据库实现一个远程聊天程序
  13. Flutter上传多张图片
  14. Linux下设置代理方法
  15. 《智能对话机器人开发实战20讲》--学习笔记--AIML基础功能拓展-与互联网的集成
  16. fone喜获“2018中国企业绩效管理信息化最佳产品奖”
  17. 飞飞cms添加广告html,飞飞cms影视系统 安装说明飞飞影视系统 建站流程
  18. cname解析教程_实战!CloudFlare使用CNAME解析并添加SSL教程
  19. python之获取本机ip
  20. java 代码模板_请按模板要求,将【代码】替换为Java程序代码

热门文章

  1. 中小学计算机教育的重要性,浅谈小学信息技术教育的重要性
  2. 计算一篇文章中英文单词的个数
  3. 无法上网dns转发_从DoH到ODoH,运营商再也不能搞DNS劫持了
  4. 王者荣耀服务器维护被扣分,王者荣耀出现大范围维护事故,无数玩家躺枪被扣分,直接被禁赛!...
  5. Arduino执行http请求GET方式
  6. PC虚拟机+树莓派摄像头运行ORB-SLAM2命令流程
  7. JAVA调用小票打印机
  8. 解决:QQ能上网,网页打不开
  9. 淘宝客订单api处理优化
  10. Linux必备软件之SSH