JAVA中的深克隆和浅克隆

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011394071/article/details/53154180

java中的深克隆和浅克隆

  • 上次说要解析okhttp的源码后部分,说来也惭愧,最近找工作也就没多少时间去整理了。其实底层封装了http协议,再往下就是Socket的封装了,再往下就是TCP/IP协议了。对于数据的传输,归根结底还是跟文件输入输出流那样,通过二进制流的形式进行通信,只是不同的层次做了不同的封装。有空再做分析了。
  • 面试过程也会需要准备一些基础知识,有些可能是常见的基础,有些可能是不太常见的,不管怎样,都要复习一下,在看设计模式的时候提到了java中的克隆,而克隆又有深克隆和浅克隆,这到底怎么区分呢
  • 结合网上的一些资料,自己写了测试,这里小结一下,并把自己的理解记下,方便后面复习。

  • 下面是我个人对概念定义的理解

浅克隆:相当于创建一个新的对象,但这个对象中包含的数据(封装的数据),与原对象封装的数据时公用的,即他们指向同一内存。


深克隆:创建新的对象,原对象封装的数据都重新分配新的内存空间来复制,值是一样的,但内存地址不同。

  • 下面通过例子来说明
  • 首先是将要被赋值的类

    package skxy.com.org;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    /**
     * @author Administrator 深克隆和浅克隆
     */
    public class Person implements Cloneable, Serializable {
        private static final long serialVersionUID = 1L;
        private String name;
        private Student student;
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
    
        public Person(String name, Student student) {
            super();
            this.name = name;
            this.student = student;
        }
    
        /* 浅复制 */
        public Object clone() throws CloneNotSupportedException {
            Person proto = (Person) super.clone();
            return proto;
        }
    
        /* 深复制 */
        public Object deepClone() throws IOException, ClassNotFoundException {
    
            /* 写入当前对象的二进制流 */
            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();
        }
    
    }
    
  • 类中封装的对象所对应的类,这里就写简单一些

    package skxy.com.org;
    
    import java.io.Serializable;
    
    /**
     * @author Administrator
     *被克隆的对象封装了这个类的引用
     */
    public class Student implements Serializable{
    
    }
    
  • 测试类

    package skxy.com.org;
    
    import java.io.IOException;
    
    public class CloneTest {
    
        public static void main(String[] args) {
            // 克隆测试
            Person person = new Person("xiaoming",new Student());
            try {
                //浅克隆
                Person clone1 = (Person) person.clone();
    
                System.out.println("person.name=" + person.getName() + " student=" + person.getStudent());
                System.out.println("clone1.name=" + clone1.getName() + " student=" + clone1.getStudent());
                System.out.println("person.getName()==clone1.getName()?");
                System.out.println(person.getName()==clone1.getName());
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
    
            //深克隆
            try {
                Person deepClone1 = (Person) person.deepClone();
                System.out.println("person.getName()==deepClone1.getName()?");
                System.out.println(person.getName()==deepClone1.getName());
                System.out.println("clone1.name=" + deepClone1.getName() + " student=" + deepClone1.getStudent());
    
            } catch (ClassNotFoundException | IOException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
  • 输出结果

    person.name=xiaoming student=skxy.com.org.Student@15db9742
    clone1.name=xiaoming student=skxy.com.org.Student@15db9742
    person.getName()==clone1.getName()?
    true
    person.getName()==deepClone1.getName()?
    false
    clone1.name=xiaoming student=skxy.com.org.Student@4eec7777
    
  • 可以看到,不管是深克隆还是浅克隆,克隆后封装的数据值是一样的,但浅克隆得到的数据内存地址是一样的,而深克隆是全新的对象。

猜你喜欢

转载自blog.csdn.net/u011394071/article/details/53154180