原型模式 —— Java的赋值、浅克隆和深度克隆的区别

赋值 直接  = ,克隆 clone

假如说你想复制一个简单变量。很简单:

int a= 5;  
int b= a;  

b = 6;

这样 a == 5, b == 6

不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。

但是如果你复制的是一个对象、list集合的情况下,情况就有些复杂了。

 

复制代码
class Student {  private int number;  public int getNumber() {  return number;  }  public void setNumber(int number) {  this.number = number;  }  }  
public class Test {  public static void main(String args[]) {  Student stu1 = new Student();  stu1.setNumber(12345);  Student stu2 = stu1;  System.out.println("学生1:" + stu1.getNumber());  System.out.println("学生2:" + stu2.getNumber());  }  
}结果:学生1:12345  
学生2:12345  
复制代码

 

这就怪了,为什么改变学生2的学号,学生1的学号也发生了变化呢?

原因出在(stu2 = stu1) 这一句。该语句的作用是将stu1的引用赋值给stu2,

这样,stu1和stu2指向内存堆中同一个对象。如图:

 

 

 

 

 

要做到 赋值的两个对象之间的内存地址重新定义

实现对象克隆有两种方式:

  1). 实现Cloneable接口并重写Object类中的clone()方法; 

复制代码
class Address implements Cloneable {  private String add;  public String getAdd() {  return add;  }  public void setAdd(String add) {  this.add = add;  }  @Override  public Object clone() {              // 下面 这个是重点Address addr = null;  try{  addr = (Address)super.clone();  }catch(CloneNotSupportedException e) {  e.printStackTrace();  }  return addr;  }  
}  
复制代码

 

2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。

复制代码
public class Outer implements Serializable{private static final long serialVersionUID = 369285298572941L;  //最好是显式声明IDpublic Inner inner;//Discription:[深度复制方法,需要对象及对象所有的对象属性都实现序列化] public Outer myclone() {Outer outer = null;try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);// 将流序列化成对象ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);outer = (Outer) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return outer;}
}
复制代码

 

 

实现对象克隆有两种方式:

  1). 实现Cloneable接口并重写Object类中的clone()方法;

  2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是优于把问题留到运行时。

注: 集合的clone,ArrayList 默认实现了cloneable,但是List<A> A对象不是深度克隆,A对象的内容也是使用同一个内存地址,所以A对象也必须实现clone

 

 

转载至:https://www.cnblogs.com/lemon-flm/p/9565695.html

转载于:https://www.cnblogs.com/mh-study/p/10514010.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个医院院长电视机坏了,拿到一个大修理店去修

一个医院院长电视机坏了&#xff0c;拿到一个大修理店去修。修理店接待人员:“OK&#xff0c;开机费50元”医院院长: “为什么还没修理就要先交费”&#xff1f;修理店接待人员: “我们修理店的制度就是这样&#xff0c;你们医院的挂号费&#xff0c;不是没看病之前就要交吗”&…

[scrum]2011/9/24-----第四天

scrum 总结&#xff1a; Team member Yesterday’s Work Today’s Work Issue R X Task201&#xff1a;Active Agenda Page的重写&#xff0c;界面设置 Task201&#xff1a;Active Agenda Page 界面的美化&#xff0c;收缩折叠&#xff0c;并添加一些动画效果 Task 243:…

c# 前后日期设置

List<string> list new List<string>(); //根据当月 显示前6个月 for(int i0;i<6;i) { list.add(DateTime.Now.AddMonths(i*-1).Tostring()); }转载于:https://www.cnblogs.com/Dcz1996/p/10515429.html

jq-AJAX 初步了解

js的异步操作(1) 定时器 (2) 事件 (3) 回调 (4) ajax Ajax优点 可以局部更新网页内容。 ajax的本质就是xmlHttpRequest对象控制台出现三个属性 readyState 请求的五个阶段 0 1 2 3 4 responseText 返回的文件内容 Status 状态吗 返回的状态信息 在__proto__有三个方法 …

ARM学习笔记7——乘法指令

ARM乘法指令完成两个数据的乘法&#xff0c;两个32位二进制数相乘的结果是64位的4积。 其中&#xff1a; 1、“RadHi:RdLo”是由RdHi(最高有效32位)和RdLo(最低有效32位)链接形成的64位数&#xff0c;“[31:0]”只选取结果的最低有效32位 2、简单的赋值由“&#xff1a;”表示…

《剑指offer》第四十三题(从1到n整数中1出现的次数)

// 面试题43&#xff1a;从1到n整数中1出现的次数 // 题目&#xff1a;输入一个整数n&#xff0c;求从1到n这n个整数的十进制表示中1出现的次数。例如 // 输入12&#xff0c;从1到12这些整数中包含1 的数字有1&#xff0c;10&#xff0c;11和12&#xff0c;1一共出现了5次。#in…

回调函数

又称callback函数。意思是指&#xff1a;在你的程序中&#xff0c;被windows系统调用的函数。 这些函数虽然由你设计&#xff0c;但是永远不会也不该被你调用&#xff0c;它们是为windows系统准备的。 窗口函数设计为callback形式&#xff0c;才能开放出一个接口给操作系统调用…

固态硬盘Ghost安装Windows 10无法引导的问题

机器配置如下&#xff1a; 电脑型号 技嘉 B360M POWER 台式电脑操作系统 Windows 10 64位 ( DirectX 12 )处理器 英特尔 Core i7-8700 3.20GHz 六核主板 技嘉 B360M POWER ( 英特尔 PCI 标准主机 CPU 桥 - CannonLake - A3…

Linux shell 内部命令与外部命令有什么区别以及怎么辨别

内部命令实际上是shell程序的一部分&#xff0c;其中包含的是一些比较简单的linux系统命令&#xff0c;这些命令由shell程序识别并在shell程序内部完成运行&#xff0c;通常在linux系统加载运行时shell就被加载并驻留在系统内存中。内部命令是写在bashy源码里面的&#xff0c;其…

[转]矩阵分解在推荐系统中的应用

矩阵分解是最近几年比较火的算法&#xff0c;经过kddcup和netflix比赛的多人多次检验&#xff0c;矩阵分解可以带来更好的结果&#xff0c;而且可以充分地考虑各种因素的影响&#xff0c;有非常好的扩展性&#xff0c;因为要考虑多种因素的综合作用&#xff0c;往往需要构造cos…

iPhone 系统刷机

1. 下载好固件(爱思 或者 pp助手) e.g. http://jailbreak.25pp.com/gujian/ 2. 将电脑与手机连接上&#xff0c;弹出iTunes软件即可 3. 长按手机电源键 关闭手机 4. 按住电源健&#xff0c;出现屏幕亮出现苹果标志后再按住Home健 5. 屏幕黑屏时松开电源健&#xff0c;继续按照H…

hdu4044

题意&#xff1a;给你一颗树有n个节点&#xff0c;树的根节点为1&#xff0c;表示为敌人的基地&#xff0c;其他叶子节点为你的基地&#xff0c;你一开始有m元&#xff0c;给你每个节点可以建造的塔的数量和塔的价格和可以照成的伤害&#xff0c;每个节点至多建立一座塔。敌人的…

RS100项目进展更新

1. 添加手机界面访问网页&#xff0c;毕竟PDA的屏幕大小和PC机大小不一致&#xff0c;完成了一自适应网页&#xff0c;便于在手机上观看实时画面&#xff1b; 2. 此项目为一个远程视频监控远程开关项目&#xff0c;远程PC机或者手机能操作到监控端的开关&#xff0c;所以在远程…

python os操作

1 # 常用的文件管理操作2 # https://www.cnblogs.com/dkblog/archive/2011/03/25/1995537.html3 import os4 import shutil5 6 # 切换工作目录,默认是在当前目录下7 # os.chdir("xx")8 9 # 当前的工作目录 D:\pythonworkspace\py_base\cn\tele\io 10 print(os.getcw…

洛谷模板,树状数组二 差分

题目链接&#xff1a;https://www.luogu.org/problemnew/show/P3368 先介绍下差分&#xff1a; 设数组a[]{1,6,8,5,10}&#xff0c;那么差分数组b[]{1,5,2,-3,5} 也就是说b[i]a[i]-a[i-1];(a[0]0;)&#xff0c;那么a[i]b[1]....b[i];(这个很好证的)。 假如区间[2,4]都加上2的话…

KMS安装后激活机器

slmgr /skms 192.168.26.82 slmgr /ato转载于:https://www.cnblogs.com/EllieSoft/p/3410320.html

Java内存模型深度解析:总结

处理器内存模型 顺序一致性内存模型是一个理论参考模型&#xff0c;JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照。JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松&#xff0c;因为如果完全按照顺序一致性模型来实现处理器和JMM&#xff0c;那么…

sourcetree,创建工作流报错:Fatal: Not a gitflow-enabled repo yet. Please run 'git flow init' first.-》解决办法...

1、打开项目下.git/config文件&#xff0c;或者如下图操作&#xff1a; 2、打开config文件以后&#xff0c;删除所有 [gitflow *条目并保存文件 3、关闭并重新打开sourcetree 4、仓库-》Git 工作流-》初始化仓库即可转载于:https://www.cnblogs.com/yxfeng/p/10536955.html

关于a标签的href属性的注意事项

今天在做一个lightbox效果的时候出现了一个问题。 当往下滚动再点击按钮出现lightbox的时候&#xff0c;lightbox的遮罩层不能铺满&#xff08;即滚动高度处不能铺上&#xff09;&#xff0c;如下图所示。原因是提交按钮使用的是a标签&#xff0c;当给a标签写上href属性的时候&…

爬虫开发4.三种数据解析方式

数据解析三种方式引言&#xff1a;回顾requests实现数据爬取的流程 指定url基于requests模块发起请求获取响应对象中的数据进行持久化存储其实&#xff0c;在上述流程中还需要较为重要的一步&#xff0c;就是在持久化存储之前需要进行指定数据解析。因为大多数情况下的需求&…