zoukankan      html  css  js  c++  java
  • 深拷贝(deep clone)与浅拷贝(shallow clone)

    浅复制(浅克隆):被复制对象的所有变量都含有与原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

     

    深复制深克隆):被复制对象的所有变量都含有与原来对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制的新对象,而不再是原有的那些被引用的对象。换言之,深复制把复制的对象所引用的对象都复制了一遍。

     

    Objectclone()方法

    将对象复制一份并返回给调用者。

    一般而言,clone方法满足:

    1.对任何的x,都有
    x.clone() != x
    克隆对象与原对象不是同个对象。

    2.对任何的对象x,都有

    x.clone().getClass() == x.getClass()

    克隆对象与原对象的类型一样

    3.如果xequals方法定义恰当中,那么

    x.clone().equals(x)

           应该成立。

    浅复制示例

    public class ColneTest

    {

        public static void main(String[] args) throws Throwable

        {

           Student s1 = new Student();

           s1.setAge(20);

           s1.setName("jack");

          

           Student s2 = (Student)s1.clone();

          

           System.out.println(s2.getAge());

           System.out.println(s2.getName());

          

           System.out.println("--------------------------");

          

           s2.setName("bob");

           System.out.println(s1.getName());

           System.out.println(s2.getName());

          

        }

    }

     

    class Student implements Cloneable

    {

        private int age;

       

        private String Name ;

     

        public int getAge()

        {

           return age;

        }

     

        public void setAge(int age)

        {

           this.age = age;

        }

     

        public String getName()

        {

           return Name;

        }

     

        public void setName(String name)

        {

           Name = name;

        }

       

        @Override

        public Object clone() throws CloneNotSupportedException

        {

           Object obj = super.clone();

          

           return obj;

        }

    }

     

     

    public class CloneTest2

    {

        public static void main(String[] args) throws Throwable

        {

           Teacher t1 = new Teacher();

           t1.setAge(40);

           t1.setName("Teacher Li");

     

           Student2 s1 = new Student2();

           s1.setAge(20);

           s1.setName("Bob");

           s1.setTeacher(t1);

     

           Student2 s2 = (Student2) s1.clone();

     

           System.out.println(s2.getAge());

           System.out.println(s2.getName());

     

           s1.getTeacher().setName("Teacher Zhang");

     

           System.out.println(s2.getTeacher().getAge());

           System.out.println(s2.getTeacher().getName());

        }

    }

     

    class Teacher implements Cloneable

    {

        private int age;

        private String name;

     

        public int getAge()

        {

           return age;

        }

     

        public void setAge(int age)

        {

           this.age = age;

        }

     

        public String getName()

        {

           return name;

        }

     

        public void setName(String name)

        {

           this.name = name;

        }

     

        @Override

        protected Object clone() throws CloneNotSupportedException

        {

           return super.clone();

        }

    }

     

    class Student2 implements Cloneable

    {

        private int age;

        private String name;

        private Teacher teacher;//浅拷贝没有复制这个对象的引用,深拷贝复制了这个对象的引用。

     

        public int getAge()

        {

           return age;

        }

     

        public void setAge(int age)

        {

           this.age = age;

        }

     

        public String getName()

        {

           return name;

        }

     

        public void setName(String name)

        {

           this.name = name;

        }

     

        public Teacher getTeacher()

        {

           return teacher;

        }

     

        public void setTeacher(Teacher teacher)

        {

           this.teacher = teacher;

        }

     

        @Override

        protected Object clone() throws CloneNotSupportedException

        {

           //手动深复制

           Student2 stu = (Student2) super.clone();

           stu.setTeacher((Teacher) stu.getTeacher().clone());

     

           return stu;

        }

    }

     

    利用序列化来做觉深复制

    把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫做反序列化(Deserialization)过程。应当指出的是,写在流里的是对象的一个拷贝,而对象仍然存在于JVM里面。

    public class CloneTest3

    {

        public static void main(String[] args) throws Exception

        {

           Teacher3 t1 = new Teacher3();

           t1.setAge(40);

           t1.setName("Teacher Li");

          

           Student3 s1 = new Student3();

           s1.setAge(20);

           s1.setName("Jack");

           s1.setTeacher(t1);

          

           Student3 s2 = (Student3)s1.deepCopy();

          

           System.out.println(s2.getAge());

           System.out.println(s2.getName());

          

           s1.getTeacher().setName("Teacher Wang");

          

           System.out.println(s2.getTeacher().getAge());

           System.out.println(s2.getTeacher().getName());

        }

    }

     

    //必须要实现Serializable接口

    class Teacher3 implements Serializable

    {

        private int age ;

        private String name;

        public int getAge()

        {

           return age;

        }

        public void setAge(int age)

        {

           this.age = age;

        }

        public String getName()

        {

           return name;

        }

        public void setName(String name)

        {

           this.name = name;

        }

       

    }

     

    //必须要实现Serializable接口这个接口是个标识接口没有定义任何方法

    class Student3 implements Serializable

    {

        private int age;

       

        private String name;

       

        private Teacher3 teacher;

     

        public int getAge()

        {

           return age;

        }

     

        public void setAge(int age)

        {

           this.age = age;

        }

     

        public String getName()

        {

           return name;

        }

     

        public void setName(String name)

        {

           this.name = name;

        }

     

        public Teacher3 getTeacher()

        {

           return teacher;

        }

     

        public void setTeacher(Teacher3 teacher)

        {

           this.teacher = teacher;

        }

       

        //用序列化的特点来进行深拷贝。无论有多少个对象引用都可以复制

        public Object deepCopy() throws Exception

        {

           ByteArrayOutputStream bos = new ByteArrayOutputStream();

          

           ObjectOutputStream oos = new ObjectOutputStream(bos);

          

           oos.writeObject(this);

          

           ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

          

           ObjectInputStream ois = new ObjectInputStream(bis);

          

           return  ois.readObject();

        }

    }

  • 相关阅读:
    西门子SCL读写DB数据
    LeetCode8.字符串转换整数(atoi) JavaScript
    LeetCode8.字符串转换整数(atoi) JavaScript
    WebRequestSugar
    iosblock用法
    datasci
    UINavigationController学习笔记
    iOSTab bar
    自定义tab bar控件 学习资料
    Ios tab Bar 使用方法
  • 原文地址:https://www.cnblogs.com/zfc2201/p/2143633.html
Copyright © 2011-2022 走看看