图文并茂的阐述clone方法 && 了解深浅拷贝的概念

clone代表克隆的意思,也就是说把一只绵羊复制粘贴一份,生成一个新的绵羊。

可以看出两只绵羊外形都是一样的,DNA是一样的。

在JAVA中也是如此,如果你希望得到一份对象的拷贝副本,那么就用克隆方法吧。

当你希望制造某个类的克隆时,先让这个类继承继承Cloneable接口

之后要复写clone方法。参照下面代码

package com.umbrella.common.test;

public class Person implements Cloneable{

    String name;
    String age;

    @Override
    public Person clone() throws CloneNotSupportedException {
        return (Person)super.clone();
    }

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

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

    public String getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void print(){
        System.out.println(this.name + "----" +  this.age);
    }
}

浅拷贝与深拷贝

深克隆与浅克隆的区别在于对复合数据类型的复制。若对象中的某个字段为复合类型,在克隆对象的时候,需要为该字段重新创建一个对象。


==============浅拷贝=============

package com.umbrella.common.test;

public class maintest {

    public static void main(String[] args) {
        try{
            Person p = new Person();
            p.setName("ljh");
            p.setAge("10");

            Person p1 = p.clone();
            p1.setName("ljh");
            p1.setAge("11");

            Person p2 = p.clone();

            p.print();
            p1.print();
            p2.print();

        System.out.println(p.getName()==p1.getName());
        System.out.println(p.getAge()==p1.getAge());
        System.out.println(p.getAge()==p2.getAge());
        System.out.println(p==p2)
} catch( Exception e){ e. printStackTrace(); } }}

执行结果:

ljh----10
ljh----11
ljh----10
true
false
true

false

用一副图来说明这个结果:



==============深拷贝=============

如果希望实现深拷贝,那么拷贝的不仅仅是Person对象了,而是对象内的每一个引用的对象也要拷贝

package com.umbrella.common.test;

public class Person implements Cloneable{

    String name;
    String age;

    @Override
    public Person clone() throws CloneNotSupportedException {
        Person newPersoon = (Person)super.clone();
        return newPersoon;
    }
//------------------------修改一下------直接New一个String--------------------------------
    public void setName(String name){
        this.name = new String(name) ;
    }

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

    public String getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void print(){
        System.out.println(this.name + "----" +  this.age);
    }
}

运行结果:

ljh----10

ljh----11
----
false
false
false
false

可以看出


这样做到了 深度拷贝。。。其实!这里有些牵强,因为String对象是通过New出来的新对象,并不是通过Clone方法实现的,暂且称之为“伪深拷贝”吧,如果希望实现真正深拷贝,可以在类中建立一个内部类,例如

首先注释掉内部类的clone调用,之后放开注释掉的部分,如下文代码所示

package com.umbrella.common.test;

public class Person implements Cloneable{
    Eat eat ;
    public Person(){
        this.eat = new Eat();
    }
    @Override
    public Person clone() throws CloneNotSupportedException {
        Person newPersoon = (Person)super.clone();
//        newPersoon.eat = this.eat.clone();            <----------注释掉的clone调用
        return newPersoon;
    }

    public  class Eat implements Cloneable{
        @Override
        public Eat clone() throws CloneNotSupportedException {
            Eat eat = (Eat)super.clone();
            return eat;
        }

    }
}

之后执行如下main方法:

package com.umbrella.common.test;

public class maintest {

    public static void main(String[] args) {
        try{
            Person p = new Person();
            Person p1 = p.clone();

            System.out.println(p==p1);
            System.out.println(p.eat==p1.eat);

        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

注释掉Clone输出结果:false true

去掉注释掉Clone输出结果:false false

因为它做到了 彻底的独立!!!

猜你喜欢

转载自blog.csdn.net/qq_31615049/article/details/80691096
今日推荐