赋值 直接  = ,克隆 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的赋值、浅克隆和深度克隆的区别相关推荐

  1. java中实现对象的深度克隆

    1.什么是深度拷贝和浅拷贝 python中有深度拷贝(也可以叫深度克隆)和浅拷贝,同样在java中很多时候需要深度拷贝对象,所谓的深度拷贝对象指的就是对于对象的所用数据及其全部进行copy一份,变成两 ...

  2. 原型模式——java实现原型模式的几种写法

    原型模式综述   原型设计模式的本质就是复制一个和自己一样的对象,这个一样指的是数据字段(feild)的一样,并且当原来的对象发生变化的时候,复制出来的对象应该是不能改变的,也就是要进行深度的克隆.j ...

  3. 原型模式 java 深浅_java学习笔记之原型模式及深浅拷贝

    一.原型模式的基本介绍 在聊原型模式之前,我们来思考一个小问题,传统的方式我们是如何克隆对象呢? 那我们以多利羊(Sheep)为例,来说明上述这个问题,具体代码见下面: 多利羊(Sheep) publ ...

  4. 原型模式 java 深浅_Java设计模式——原型模式

    原型模式(Prototype) 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对 ...

  5. 原型模式以及深克隆和浅克隆

    原型模式的好处 创建比较复杂的对象,无需考虑过程,简化了创建对象的创建过程,同时也能提 高效率 原型模式分为浅克隆和深克隆,不同点 以我目前的理解:深克隆和浅克隆对于我们对象内的引用对象的克隆不一样 ...

  6. java深度克隆_浅析Java中clone()方法浅克隆与深度克隆

    现在Clone已经不是一个新鲜词语了,伴随着"多莉"的产生这个词语确实很"火"过一阵子,在Java中也有这么一个概念,它可以让我们很方便的"制造&qu ...

  7. Java clone() 浅克隆与深度克隆(转)

    以下文字转自:桔子园 http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.html 现在Clone已经不是一个新鲜词语了,伴随着& ...

  8. 原型模式 java 深浅_JAVA设计模式---原型模式--浅客隆和深克隆

    JAVA浅克隆和深克隆 浅克隆:被复制对象的所有变量和原来相同,而所有的对其他对象的引用仍指向原对象.即如果复制的对象修改复制对象的变量,原对象不会改变.而修改引用的对象,二者均会发生改变. 深复制( ...

  9. Java原型模式(prototype)

      prototype模式也就是原型模式,是javaGOF23种设计模式中的一种,我们在学习spring的时候在bean标签的学习中碰到过,所以本文来给大家介绍下原型模式 原型模式   在java中我 ...

最新文章

  1. LeetCode-笔记-57.插入区间
  2. 推荐抓虾在线RSS阅读
  3. 史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon)
  4. boost的chrono模块特殊值的测试程序
  5. android dialog 隐藏状态栏_Android应用视图的管理者Window
  6. 简单的聊聊,顺便招前端
  7. Codeforces Round #645 (Div. 2)(AB)
  8. dash使用_使用Dash和SHAP构建和部署可解释的AI仪表盘
  9. C#读书雷达 | TW洞见
  10. spring使用自定义注解_用Spring组成自定义注释
  11. 【重识 HTML + CSS】基本 CSS 属性
  12. 「AI原生」时代来临?百度智能云提出AI-Native,发布新一代云基础架构「太行」
  13. YII with()
  14. 自制力差?!教你强迫自己学习
  15. Linux服务器遇到攻击怎么办?用这些方法封禁IP
  16. 任天堂被黑了!早期游戏源码及设计图大批曝光,原来塞尔达传说还有个血腥版本?
  17. 产品体验报告:百度贴吧
  18. 项目经理面试题pmp面试题项目管理面试题
  19. 贝格尔编排法的PHP实现
  20. uniapp 电子印章_Uni-app 之文章案例

热门文章

  1. tf.nn.dropout和tf.keras.layers.Dropout的区别(TensorFlow2.3)与实验
  2. 计算机非211研究生,这所大学不是211,但“计算机”实力远超985,快来看看
  3. 建立一个laravel项目
  4. pic10f220 c语言,PIC10F200 LED流水灯程序
  5. 『设计模式』就因为多收了我2块5,我追着收银员问是不是不懂设计模式--策略模式
  6. USACO Training Section 1.1 坏掉的项链Broken Necklace
  7. 如何在ubuntu下安装source insight
  8. 【边缘检测】BDCN:Bi-Directional Cascade Network for Perceptual Edge Detection
  9. 计算机视觉课_计算机视觉教程—第4课
  10. 欢迎使用CSDN-markdown编辑器111