原型模式 —— 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
原型模式 —— Java的赋值、浅克隆和深度克隆的区别相关推荐
- java中实现对象的深度克隆
1.什么是深度拷贝和浅拷贝 python中有深度拷贝(也可以叫深度克隆)和浅拷贝,同样在java中很多时候需要深度拷贝对象,所谓的深度拷贝对象指的就是对于对象的所用数据及其全部进行copy一份,变成两 ...
- 原型模式——java实现原型模式的几种写法
原型模式综述 原型设计模式的本质就是复制一个和自己一样的对象,这个一样指的是数据字段(feild)的一样,并且当原来的对象发生变化的时候,复制出来的对象应该是不能改变的,也就是要进行深度的克隆.j ...
- 原型模式 java 深浅_java学习笔记之原型模式及深浅拷贝
一.原型模式的基本介绍 在聊原型模式之前,我们来思考一个小问题,传统的方式我们是如何克隆对象呢? 那我们以多利羊(Sheep)为例,来说明上述这个问题,具体代码见下面: 多利羊(Sheep) publ ...
- 原型模式 java 深浅_Java设计模式——原型模式
原型模式(Prototype) 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对 ...
- 原型模式以及深克隆和浅克隆
原型模式的好处 创建比较复杂的对象,无需考虑过程,简化了创建对象的创建过程,同时也能提 高效率 原型模式分为浅克隆和深克隆,不同点 以我目前的理解:深克隆和浅克隆对于我们对象内的引用对象的克隆不一样 ...
- java深度克隆_浅析Java中clone()方法浅克隆与深度克隆
现在Clone已经不是一个新鲜词语了,伴随着"多莉"的产生这个词语确实很"火"过一阵子,在Java中也有这么一个概念,它可以让我们很方便的"制造&qu ...
- Java clone() 浅克隆与深度克隆(转)
以下文字转自:桔子园 http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.html 现在Clone已经不是一个新鲜词语了,伴随着& ...
- 原型模式 java 深浅_JAVA设计模式---原型模式--浅客隆和深克隆
JAVA浅克隆和深克隆 浅克隆:被复制对象的所有变量和原来相同,而所有的对其他对象的引用仍指向原对象.即如果复制的对象修改复制对象的变量,原对象不会改变.而修改引用的对象,二者均会发生改变. 深复制( ...
- Java原型模式(prototype)
prototype模式也就是原型模式,是javaGOF23种设计模式中的一种,我们在学习spring的时候在bean标签的学习中碰到过,所以本文来给大家介绍下原型模式 原型模式 在java中我 ...
最新文章
- LeetCode-笔记-57.插入区间
- 推荐抓虾在线RSS阅读
- 史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon)
- boost的chrono模块特殊值的测试程序
- android dialog 隐藏状态栏_Android应用视图的管理者Window
- 简单的聊聊,顺便招前端
- Codeforces Round #645 (Div. 2)(AB)
- dash使用_使用Dash和SHAP构建和部署可解释的AI仪表盘
- C#读书雷达 | TW洞见
- spring使用自定义注解_用Spring组成自定义注释
- 【重识 HTML + CSS】基本 CSS 属性
- 「AI原生」时代来临?百度智能云提出AI-Native,发布新一代云基础架构「太行」
- YII with()
- 自制力差?!教你强迫自己学习
- Linux服务器遇到攻击怎么办?用这些方法封禁IP
- 任天堂被黑了!早期游戏源码及设计图大批曝光,原来塞尔达传说还有个血腥版本?
- 产品体验报告:百度贴吧
- 项目经理面试题pmp面试题项目管理面试题
- 贝格尔编排法的PHP实现
- uniapp 电子印章_Uni-app 之文章案例
热门文章
- tf.nn.dropout和tf.keras.layers.Dropout的区别(TensorFlow2.3)与实验
- 计算机非211研究生,这所大学不是211,但“计算机”实力远超985,快来看看
- 建立一个laravel项目
- pic10f220 c语言,PIC10F200 LED流水灯程序
- 『设计模式』就因为多收了我2块5,我追着收银员问是不是不懂设计模式--策略模式
- USACO Training Section 1.1 坏掉的项链Broken Necklace
- 如何在ubuntu下安装source insight
- 【边缘检测】BDCN:Bi-Directional Cascade Network for Perceptual Edge Detection
- 计算机视觉课_计算机视觉教程—第4课
- 欢迎使用CSDN-markdown编辑器111