Java深克隆和浅克隆 - Go语言中文社区

Java深克隆和浅克隆


为什么要用clone?

    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中

已经包含了一些有效值,此时可能会需要一个和A完全相同的新对象B,并且以

后对B任何改动都不会影响A中的值,也就是说A与B是两个独立的对象,但B的

初始值由A对象确定的.  在Java语言中用简单的赋值语句是不能满足这种需求的.

要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单的也是最高效的手段.

new一个对象的过程和clone一个对象的过程区别

    new操作符的本意是分配内存.程序执行到new操作符时,首先去看new操作符后面的类型,

因为知道了类型才能知道要分配多大的内存空间.   分配完内存以后,再调用构造函数,

填充对象的各个域.  这一步叫做初始化.构造方法返回后,一个对象创建完毕, 

可以把它的引用(地址)发布到外部, 在外部就可以使用这个引用操作这个对象.

        clone在第一步和new相似, 都是分配内存,调用clone方法时, 分配的内存

和原对象(调用clone方法的对象)相同, 然后再使用原对象中对应的各个域填充

新对象的域,  填充完成之后,  clone方法返回一个新的相同的对象,同样可以把这

个新对象的引用发布到外部,就可以使用这个引用操作这个新对象.

浅克隆和深克隆(深拷贝和浅拷贝)

     定义一个Person对象类实现Cloneable接口重写clone()方法如下:

package com.ganbo;

/**
 * Created by gan on 2018/3/13 17:18.
 */
public class Person implements Cloneable {

    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return super.toString();
    }


}

编写测试代码:

public static void main(String[] args) throws CloneNotSupportedException {
    Person p1 = new Person("Bruce", 23);
    Person p2 = (Person) p1.clone();   //克隆对象

    System.out.println(p1 == p2);

    System.out.println(p1.getName() == p2.getName());

}

运行结果为:


false证明调用clone方法是克隆了一个新对象.

true表示p1和p2对象name属性其实还是同一个字符串对象. 这种调用克隆方法后属性并没有创建新对象叫

浅克隆.所以克隆方法执行调用的是浅拷贝,在编写程序的时候就要注意这个细节.


如何进行深拷贝 ?

    如果要想深拷贝一个对象,这个对象必须实现Cloneable接口,实现clone方法,    并且在clone方法内部要把

该对象的其他对象也要clone一份,   这就要求这个这个被引用的对象也必须要实现Cloneable接口并实现clone

方法.   那么如下代码所示:

package com.ganbo;

/**
 * Created by gan on 2018/3/13 17:18.
 */
public class Person implements Cloneable {

    private Integer age;
    private Book book;

    public Person(Integer age, Book book) {
        this.age = age;
        this.book = book;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    public Integer getAge() {
        return age;
    }


    /**
     * 实现clone方法,并且在方法中把依赖的对象也clone一份
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person newPerson = (Person) super.clone();
        newPerson.book = (Book) book.clone();
        return  newPerson;
    }


}

class Book implements Cloneable {

    private Long id;

    public Book(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

编写测试代码:

public static void main(String[] args) throws CloneNotSupportedException {
    Person p1 = new Person(23,new Book(12L));
    Person p2 = (Person) p1.clone();   //克隆对象
    System.out.println(p1.book == p2.book);

}
打印结果为:


完成深克隆.

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u010972055/article/details/79575440
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 13:18:37
  • 阅读 ( 545 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢