关于浅克隆和深克隆入门理解

浅克隆:需要类实现Cloneable,并重写clone()方法

一般在重写clone()方法时,将返回值类型强转为自己类,避免每次克隆之后需要强转

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        A a1=new A();
        A a2 = a1.clone();

        //克隆之后 a1和a2是两个不同对象  内容相同
        System.out.println(a1==a2);//false
        System.out.println(a1);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
        System.out.println("--------------------------------------");

        //浅克隆之后,对String类型和8种基本类型(包装类)的改变不会影响另外一个对象的属性内容
        a1.setA(5);
        a1.setB(6);
        a1.setC("7");
        a1.setE("8");
        System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='1'}, e='8'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
        System.out.println("--------------------------------------");

        //但是浅克隆对自定义类型的成员变量的改变,会影响另外一个对象 说明自定义对象在a1和a2中的引用地址指向了同一个对象
        a1.getD().setName("改了");
        System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='改了'}, e='8'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='改了'}, e='4'}
        a2.getD().setName("又改了");
        System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='又改了'}, e='8'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='又改了'}, e='4'}

    }

}
class A implements Cloneable{
    int a=1;
    Integer b=2;
    String c=new String("3");
    D d=new D();
    String e="4";

    @Override
    public String toString() {
        return "A{" +
                "a=" + a +
                ", b=" + b +
                ", c='" + c + '\'' +
                ", d=" + d +
                ", e='" + e + '\'' +
                '}';
    }

    public D getD() {
        return d;
    }

    public void setD(D d) {
        this.d = d;
    }

    public String getE() {
        return e;
    }

    public void setE(String e) {
        this.e = e;
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public Integer getB() {
        return b;
    }

    public void setB(Integer b) {
        this.b = b;
    }

    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    @Override
    protected A clone() throws CloneNotSupportedException {
        return (A)super.clone();
    }
}
class D{
    String name="1";

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "D{" +
                "name='" + name + '\'' +
                '}';
    }
}

画张图表示

关于浅克隆和深克隆入门理解_第1张图片

下面是深克隆的一种写法

让自定义类也实现克隆,并重写clone方法

关于浅克隆和深克隆入门理解_第2张图片

然后在对象类的克隆方法改写成下面

关于浅克隆和深克隆入门理解_第3张图片

这样再运行上面代码,  D就是不同的对象了,克隆之后,无论谁改变d的属性,都只影响自己

以集成工具默认重写equals和hashcode不影响执行结果

深克隆还有其他写法

你可能感兴趣的:(java,算法,开发语言)