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

深克隆和淺克隆

標籤(空格分隔): 設計模式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}
相關文章
相關標籤/搜索