• Cloneable 和clone的区别和联系


    设计模式----原型模式时候,涉及到的复制克隆,

        Cloneable 接口,内部是没有任何方法的,

    这个接口其实是一个标记性的接口,和Serializable是一样的,都是标记使用,

     在类实现了这个Cloneable 接口后调用Object中得clone方法,才可以正常的使用,如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。 

    在复制中,分为浅复制和深复制;

    先说浅复制:

    其实这样的复制是一种很危险的复制,有时候预期效果并不是你想要的!

     1 package Method.clone;
     2 
     3 public class Student implements Cloneable 
     4 {
     5     private int id;
     6     private String name;
     7     public StringBuffer sb = new StringBuffer("");
     8 
     9     public Student() {
    10         this.id = 744;
    11         this.name = "FL";
    12     }
    13 
    14     public Student(int id, String name) {
    15         this.id = id;
    16         this.name = name;
    17     }
    18 
    19     public boolean equals(Object obj) {
    20         return this.id == ((Student) obj).id;
    21     }
    22 
    23     public String toString() {
    24         return "Student id : " + id + " Name " + name;
    25     }    
    26 
    27     public static void main(String[] args) throws CloneNotSupportedException // 这里为什么一定得写
    28     {
    29         Student s1 = new Student(101, "WangQiang");
    30         Student s2 = (Student) s1.clone();
    31         System.out.println(s1 == s2);
    32         System.out.println(s1);
    33         System.out.println(s2);
    34 
    35         s1.sb.append("s1's string");
    36         System.out.println("s2.sb's value = " + s2.sb.toString());
    37         System.out.println(s1.sb==s2.sb);
    38         
    39     }
    40 }

    浅层拷贝导致s1和s2共享同一个StringBuffer对象,s2还是可以调用s1中得StringBuffer。这样的复制还是很危险!

    Object中提供的clone方法是一种浅复制,对于基本类型的字段,可以说它成功克隆了。但对于对象型字段,它并没有实现克隆的功能,仅仅做了一个赋值。(拷贝基本成员属性,对于引用类型仅返回指向改地址的引用)

     

     深复制: 

           首先这个对象必须实现了Serializable 接口,可以被序列化,和反序列化:深复制时候采用的是流进行读写的,原对象还是存在JVM中

    序列化前和序列化后的对象的关系


    反序列化还原后的对象地址与原来的的地址不同,序列化前后对象的地址不同了,但是内容是一样的,而且对象中包含的引用也相同。换句话说,通过序列化操作,我们可以实现对任何可Serializable对象的”深度复制(deep copy)"——这意味着我们复制的是整个对象网,而不仅仅是基本对象及其引用。对于同一流的对象,他们的地址是相同,说明他们是同一个对象,但是与其他流的对象地址却不相同。也就说,只要将对象序列化到单一流中,就可以恢复出与我们写出时一样的对象网,而且只要在同一流中,对象都是同一个。

     1 public  Object deepClone() throws IOException, ClassNotFoundException{
     2         //将对象写到流里
     3         ByteArrayOutputStream bos = new ByteArrayOutputStream();
     4         ObjectOutputStream oos = new ObjectOutputStream(bos);
     5         oos.writeObject(this);
     6         //从流里读回来
     7         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
     8         ObjectInputStream ois = new ObjectInputStream(bis);
     9         return ois.readObject();
    10     }

    对具体分析:参考博客 

     http://www.cnblogs.com/tonyluis/p/5779187.html
    
    
  • 相关阅读:
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day7
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day6
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day5
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day4
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day3
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day2
    20172328--蓝墨云班课实验--哈夫曼树的编码
    《团队作业》五小福团队--UNO的博客链接汇总
    《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day1--领航
    题目 2239: [蓝桥杯][算法训练]动态数组使用(Java)
  • 原文地址:https://www.cnblogs.com/java-synchronized/p/6684535.html
Copyright © 2020-2023  润新知