Clone方法与浅拷贝深拷贝
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方法与浅拷贝深拷贝相关推荐
- 详解Java中的clone方法 -- 深拷贝和浅拷贝
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- 详解Java中的clone方法 -- 原型模式
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- 对象的克隆(clone方法)
1.深拷贝与浅拷贝 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象.深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象. 2.深拷贝和浅拷贝的 ...
- Java基础篇:对象拷贝:clone方法 以及 序列化
我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...
- 关于Java的Object.clone()方法与对象的深浅拷贝,java面试题,java初级笔试题
写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...
- Java基础深度总结:Object类-clone方法
凡心所向,素履所往,生如逆旅,一苇以航. 内容 1.clone概述 2.Cloneable接口 3.clone与new的区别 4.浅拷贝与深拷贝(重点) 5.Object.clone 6.浅拷贝存在的 ...
- java cloneable_java开发——Cloneable接口、clone()方法和深浅拷贝
1.实现Cloneable接口表明该类的对象是允许克隆的. 2.允许克隆的意思是:可以调用clone()方法. 3.深拷贝还是浅拷贝,取决于如何重写Object的clone()方法. 4.原对象和克隆 ...
- java中clone方法的理解(深拷贝、浅拷贝)
文章目录 前言: 知识点一:什么是浅拷贝? 知识点二:什么是深拷贝? 知识点三.java拷贝(clone)的前提: 知识点四:浅拷贝案例: 拷贝类: 测试类: 总结: 下面通过画图示意: 知识点五:深 ...
- 【java】克隆(clone),浅拷贝和深拷贝的区别
前言 在很多人初学的时候,一定会被克隆是什么?怎么使用克隆?浅拷贝和深拷贝又是啥?所搞得晕头转向.这里我希望用最简单的语言向大家介绍我自己的理解.(我们马克思老师说,你能不能用农民也听得懂的语言介绍一 ...
最新文章
- STM32:Flash擦除与读写操作(HAL库)
- 阶乘与斐波那契数的理解
- AAAI2021论文合集汇总!(持续更新)
- 每周一荐:foobar2000, 奇幻人生, 一个Flash小游戏
- java byte md5_Java开发网 - byte[]按自定义编码转换成String(MD5)
- List、Map、Set之间的联系与区别:
- 绿色iPhone 13和紫色iPad Air将在明天发布?网友:苹果又寻思在配色上“整活儿”...
- 【Flink】Flink 上海会议 【视频笔记】
- webrtc系列3——对于stun和turn的理解
- 计算机基础a3知识点,《计算机应用基础》期末试卷A(A3版).doc
- 8086中寻址方式详解
- 使用Android Studio和阿里云数据库实现一个远程聊天程序
- Flutter上传多张图片
- Linux下设置代理方法
- 《智能对话机器人开发实战20讲》--学习笔记--AIML基础功能拓展-与互联网的集成
- fone喜获“2018中国企业绩效管理信息化最佳产品奖”
- 飞飞cms添加广告html,飞飞cms影视系统 安装说明飞飞影视系统 建站流程
- cname解析教程_实战!CloudFlare使用CNAME解析并添加SSL教程
- python之获取本机ip
- java 代码模板_请按模板要求,将【代码】替换为Java程序代码