標籤(空格分隔): 設計模式java
原型模式: 將一個對象做爲原型, 經過對其進行復制而克隆出多個和原型相似的新實例.設計模式
淺克隆: 被複制對象的全部基本變量都含有和原來變量徹底相同的值, 而其餘全部的引用對象任然指向原來的對象. 換言之, 淺克隆僅僅複製鎖考慮的對象, 而不復制它所引用的對象. 克隆的深度僅僅到棧內存中.ide
深克隆: 和淺克隆不同的點在於其重寫了clone函數. 在克隆自己對象的時候, 也對其中的引用類型的屬性進行克隆.函數
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}