深克隆和浅克隆 / 原型模式

深克隆和浅克隆

标签(空格分隔): 设计模式java


原型模式: 将一个对象做为原型, 经过对其进行复制而克隆出多个和原型相似的新实例.设计模式

浅克隆

浅克隆: 被复制对象的全部基本变量都含有和原来变量彻底相同的值, 而其余全部的引用对象任然指向原来的对象. 换言之, 浅克隆仅仅复制锁考虑的对象, 而不复制它所引用的对象. 克隆的深度仅仅到栈内存中.ide

深克隆

深克隆: 和浅克隆不同的点在于其重写了clone函数. 在克隆自己对象的时候, 也对其中的引用类型的属性进行克隆.函数


  • 看下面的代码, 为何String就这么吊, 好像直接就是深克隆呢?
  • 不一样点在于, 在浅克隆的时候 gg属性是 栈内存地址不变, 咱们改变了它堆内存的地址, 这样致使两个对象的gg都变了. name属性是栈内存地址直接就变了.

package reBegin;



public class CloneDemo{
    public static void main(String[] args) throws CloneNotSupportedException {
        /* 浅克隆 */
        WeakTestClone testClone = new WeakTestClone(1,"阿狗", new GG(77));
        WeakTestClone cloneWeak = (WeakTestClone) testClone.clone();
//      这样会将全部克隆体和被克隆体的引用改变, 由于getGg() 获得了栈内存地址, setAge()的时候改变了堆内存的地址.
//      由于两个对象的引用属性是指向同一个堆内存地址的,因此两个对象的gg 属性就改变了.
        testClone.getGg().setAge(110);
        testClone.setName("JackMa");

        
        System.out.println(testClone);
        System.out.println(cloneWeak);

        /* 深克隆 */
        StrongTestClone strongTestClone = new StrongTestClone(1,"阿狗",new GG(77));
        StrongTestClone cloneStrong = (StrongTestClone) strongTestClone.clone();
//      StrongTestClone 重写了clone函数, 在其中将其 gg 属性也一并克隆.
//      这个时候对象中的gg属性, 存储的堆内存地址就不同了.  是两个彻底不一样的对象.
        strongTestClone.getGg().setAge(111);
        strongTestClone.setName("JackMa");

        System.out.println(strongTestClone);
        System.out.println(cloneStrong);

    }
}

/**
 * 浅克隆, 只会克隆 仅仅拷贝对象自己, 也就是拷贝的深度仅限于栈内存.
 */
class WeakTestClone implements Cloneable{
    private int age;
    private String name;
    private GG gg;

    WeakTestClone() {
    }

    WeakTestClone(int age, String name, GG gg) {
        this.age = age;
        this.name = name;
        this.gg = gg;
    }

    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 GG getGg() {
        return gg;
    }

    public void setGg(GG gg) {
        this.gg = gg;
    }

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

    @Override
    public String toString() {
        return "testClone{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", gg=" + gg.getAge() +
                '}';
    }
}
class StrongTestClone implements Cloneable{
    private int age;
    private String name;
    private GG gg;

    public StrongTestClone() {
    }

    public StrongTestClone(int age, String name, GG gg) {
        this.age = age;
        this.name = name;
        this.gg = gg;
    }

    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 GG getGg() {
        return gg;
    }

    public void setGg(GG gg) {
        this.gg = gg;
    }

    @Override
    public String toString() {
        return "StrongTestClone{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", gg=" + gg.getAge() +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        StrongTestClone strongTestClone = (StrongTestClone) super.clone();
        strongTestClone.setGg((GG)gg.clone());
        return strongTestClone;
    }
}

class GG implements Cloneable{
    private int age;

    public GG() {
    }

    GG(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
<!-- 结果 -->
testClone{age=1, name='JackMa', gg=110}
testClone{age=1, name='阿狗', gg=110}
StrongTestClone{age=1, name='JackMa', gg=111}
StrongTestClone{age=1, name='阿狗', gg=77}
相关文章
相关标签/搜索