復制對象與復制引用


原型模式:(復制對象)
1.復制"引用"與復制"對象"的區別   1.1復制"引用"---復制地址   假設被復制對象為A a,復制的新對象為A b.   復制引用的過程就是將a的地址值復制給b.a和b同時指向堆內存的同一個地址. 過程為:
1 A a = new A(); 2 A b = a; 
這樣,只要其中一個對象的屬性發生變化,另一個對象的屬性也隨之發生變化.  

根據"復制引用"編寫程序:
 
        
 1 public class Student {  2     
 3     public static void main(String[] args) {  4         Student s1 = new Student("張三", 23);  5         Student s2 = s1;  6         System.out.println(s1 == s2);  7  System.out.println(s1);  8  System.out.println(s2);  9         
10         //1.改變s1的名字
11         s1.setName("李四"); 12         System.out.println(s1 == s2); 13  System.out.println(s1); 14  System.out.println(s2); 15         
16         //1.改變s1的名字
17         s2.setName("王五"); 18         System.out.println(s1 == s2); 19  System.out.println(s1); 20  System.out.println(s2); 21  } 22     
23     private String name; 24     private int age; 25     
26     public Student() {} 27 
28     public Student(String name, int age) { 29         this.name = name; 30         this.age = age; 31  } 32 
33     public String getName() { 34         return name; 35  } 36 
37     public void setName(String name) { 38         this.name = name; 39  } 40 
41     public int getAge() { 42         return age; 43  } 44 
45     public void setAge(int age) { 46         this.age = age; 47  } 48 
49  @Override 50     public String toString() { 51         return "Student [name=" + name + ", age=" + age + "]"; 52  } 53 }
程序運行結果:
 1 true
 2 Student [name=張三, age=23]  3 Student [name=張三, age=23]  4 
 5 true
 6 Student [name=李四, age=23]  7 Student [name=李四, age=23]  8 
 9 true
10 Student [name=王五, age=23] 11 Student [name=王五, age=23]
1.2復制"對象"---復制內容
  假設被復制對象為Student s1,復制的新對象為Student s2.
  Student類有兩個屬性,name 和 age;
  復制對象的過程:
  ①:Student s1 = new Student("張三", 23);
  ②:Student s2 = new Student();
  ③:s2.setName(s1.getName());
     s2.setAge(s1.getAge());
  s1與s2是兩個不同的對象,保存相同的屬性及其屬性值.當s1的屬性值發生變化時,s2的屬性值不會受到影響.s1與s2相互獨立.
 
根據"復制對象的過程"編寫程序:
 1 public class Student {  2     
 3     public static void main(String[] args) {  4         Student s1 = new Student("張三", 23);  5         Student s2 = new Student();  6 
 7  s2.setName(s1.getName());  8  s2.setAge(s1.getAge());  9         System.out.println(s1 == s2); 10  System.out.println(s1); 11  System.out.println(s2); 12         
13         s1.setName("李四"); 14  System.out.println(s1); 15  System.out.println(s2); 16         
17         s2.setName("王五"); 18  System.out.println(s1); 19  System.out.println(s2); 20  } 21     
22     private String name; 23     private int age; 24     
25     public Student() {} 26 
27     public Student(String name, int age) { 28         this.name = name; 29         this.age = age; 30  } 31 
32     public String getName() { 33         return name; 34  } 35 
36     public void setName(String name) { 37         this.name = name; 38  } 39 
40     public int getAge() { 41         return age; 42  } 43 
44     public void setAge(int age) { 45         this.age = age; 46  } 47 
48  @Override 49     public String toString() { 50         return "Student [name=" + name + ", age=" + age + "]"; 51  } 52 }

 

程序運行結果:
1 false
2 Student [name=張三, age=23] 3 Student [name=張三, age=23] 4 
5 Student [name=李四, age=23] 6 Student [name=張三, age=23] 7 
8 Student [name=李四, age=23] 9 Student [name=王五, age=23]
2.原型模式
  2.1假設對象的屬性特征很簡單:(直接賦值,不需要new對象來賦值)
  例:情況1.
1 class Person{ 2     private String name; 3     private int age; 4 }
那么:實現對象復制的過程很簡單.
思路A:
①:Person類實現Cloneable接口.
    Cloneable是一個標識性接口,沒有抽象方法.實現這個接口的類被標記為可以被克隆.
②:Person類重寫clone()方法.
根據思路A編寫程序:
 1 public class Person implements Cloneable{  2     
 3     public static void main(String[] args) throws CloneNotSupportedException {  4         // 測試  5         //原型
 6             Person person = new Person("張三", 23);  7         //克隆對象
 8             Person clonePerson = (Person)person.clone();  9         System.out.println(person == clonePerson); 10  System.out.println(person); 11  System.out.println(clonePerson); 12         
13            //1.改變person的名字和對象
14         person.setName("李四"); 15         person.setAge(24); 16  System.out.println(person); 17  System.out.println(clonePerson); 18         
19             //2.改變clonePerson的名字和對象
20         clonePerson.setName("王五"); 21         clonePerson.setAge(25); 22  System.out.println(person); 23  System.out.println(clonePerson); 24  } 25 
26     private String name; 27     private int age; 28     public Person(String name, int age) { 29         this.name = name; 30         this.age = age; 31  } 32     public Person() {} 33     public String getName() { 34         return name; 35  } 36     public void setName(String name) { 37         this.name = name; 38  } 39     public int getAge() { 40         return age; 41  } 42     public void setAge(int age) { 43         this.age = age; 44  } 45  @Override 46     public String toString() { 47         return "Person [name=" + name + ", age=" + age + "]"; 48  } 49     public Object clone() throws CloneNotSupportedException { 50         Person person = (Person)super.clone(); 51         return person; 52  } 53 }
程序運行結果:
1 false
2 Person [name=張三, age=23] 3 Person [name=張三, age=23] 4 
5 Person [name=李四, age=24] 6 Person [name=張三, age=23] 7 
8 Person [name=李四, age=24] 9 Person [name=王五, age=25]

 

2.1假設對象的某些屬性特征較復雜:(需要new對象來賦值)
例:情況2.
 1 class Person{  2     private String name;  3     private int age;  4     private Company com;  5 }  6 
 7 
 8 class Company{  9     private String name; 10     private int age; 11     private String address; 12 }
在情況2下能夠采用思路A編程嗎?
讓我們來試一試:思路A
 1 public class Person implements Cloneable{  2     
 3     public static void main(String[] args) throws CloneNotSupportedException {  4         // 測試  5         //1.創建原型對象
 6         Company com = new Company("tencent", 5, "深圳");  7         Person person = new Person("張三", 23, com);  8         //原型克隆
 9         Person clonePerson = (Person)person.clone(); 10         System.out.println(person == clonePerson); 11  System.out.println(person); 12  System.out.println(clonePerson); 13         
14         //2.改變原型對象的com
15         Company personCom = person.getCom(); 16         personCom.setName("alibaba"); 17         personCom.setAge(3); 18         personCom.setAddress("杭州"); 19  System.out.println(person); 20  System.out.println(clonePerson); 21         
22         //3.改變克隆對象的com
23         Company clonePersonCom = clonePerson.getCom(); 24         clonePersonCom.setName("baidu"); 25         clonePersonCom.setAge(4); 26         clonePersonCom.setAddress("beijing"); 27  System.out.println(person); 28  System.out.println(clonePerson); 29  } 30 
31     private String name; 32     private int age; 33     private Company com; 34     
35     public Person() {} 36     
37     public Person(String name, int age, Company com) { 38         this.name = name; 39         this.age = age; 40         this.com = com; 41  } 42     
43     public String getName() { 44         return name; 45  } 46     public void setName(String name) { 47         this.name = name; 48  } 49     public int getAge() { 50         return age; 51  } 52     public void setAge(int age) { 53         this.age = age; 54  } 55     public Company getCom() { 56         return com; 57  } 58 
59     public void setCom(Company com) { 60         this.com = com; 61  } 62     
63  @Override 64     public String toString() { 65         return "Person [name=" + name + ", age=" + age + ", com=" + com + "]"; 66  } 67     public Object clone() throws CloneNotSupportedException { 68         Person person = (Person)super.clone(); 69         return person; 70  } 71 }

 

 
        
 1 public class Company implements Cloneable{  2 
 3     private String name;  4     private int age;  5     private String address;  6     public Company() {  7  }  8     public Company(String name, int age, String address) {  9         this.name = name; 10         this.age = age; 11         this.address = address; 12  } 13     public String getName() { 14         return name; 15  } 16     public void setName(String name) { 17         this.name = name; 18  } 19     public int getAge() { 20         return age; 21  } 22     public void setAge(int age) { 23         this.age = age; 24  } 25     public String getAddress() { 26         return address; 27  } 28     public void setAddress(String address) { 29         this.address = address; 30  } 31     
32  @Override 33     public String toString() { 34         return "Company [name=" + name + ", age=" + age + ", address=" + address + "]"; 35  } 36 }
程序運行結果:
1 false
2 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 3 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 4 
5 Person [name=張三, age=23, com=Company [name=alibaba, age=3, address=杭州]] 6 Person [name=張三, age=23, com=Company [name=alibaba, age=3, address=杭州]] 7 
8 Person [name=張三, age=23, com=Company [name=baidu, age=4, address=beijing]] 9 Person [name=張三, age=23, com=Company [name=baidu, age=4, address=beijing]]
這時會發現,已經有錯誤產生了.
當我們改動person或者clonePerson的com值時,另一個對象的com也會隨之發生改變.
修改方法:思路B
①:Person, Company都要實現Cloneable接口.
②:在對Person對象進行克隆的同時也要對Company對象進行克隆.
根據思路B編寫程序:
 1 public class Person implements Cloneable{  2     
 3     public static void main(String[] args) throws CloneNotSupportedException {  4         // 測試  5         //1.創建原型對象
 6         Company com = new Company("tencent", 5, "深圳");  7         Person person = new Person("張三", 23, com);  8         //原型克隆
 9         Person clonePerson = (Person)person.clone(); 10         System.out.println(person == clonePerson); 11  System.out.println(person); 12  System.out.println(clonePerson); 13         
14         //2.改變原型對象的com
15         Company personCom = person.getCom(); 16         personCom.setName("alibaba"); 17         personCom.setAge(3); 18         personCom.setAddress("杭州"); 19  System.out.println(person); 20  System.out.println(clonePerson); 21         
22         //3.改變克隆對象的com
23         Company clonePersonCom = clonePerson.getCom(); 24         clonePersonCom.setName("baidu"); 25         clonePersonCom.setAge(4); 26         clonePersonCom.setAddress("北京"); 27  System.out.println(person); 28  System.out.println(clonePerson); 29  } 30 
31     private String name; 32     private int age; 33     private Company com; 34     
35     public Person() {} 36     
37     public Person(String name, int age, Company com) { 38         this.name = name; 39         this.age = age; 40         this.com = com; 41  } 42     
43     public String getName() { 44         return name; 45  } 46     public void setName(String name) { 47         this.name = name; 48  } 49     public int getAge() { 50         return age; 51  } 52     public void setAge(int age) { 53         this.age = age; 54  } 55     public Company getCom() { 56         return com; 57  } 58 
59     public void setCom(Company com) { 60         this.com = com; 61  } 62     
63  @Override 64     public String toString() { 65         return "Person [name=" + name + ", age=" + age + ", com=" + com + "]"; 66  } 67     public Object clone() throws CloneNotSupportedException { 68         Person person = (Person)super.clone();//克隆Person
69         person.setCom((Company)com.clone());//克隆Company
70         return person; 71  } 72 }

 

 
        
 1 public class Company implements Cloneable{  2     
 3     private String name;  4     private int age;  5     private String address;  6     public Company() {  7  }  8     public Company(String name, int age, String address) {  9         this.name = name; 10         this.age = age; 11         this.address = address; 12  } 13     public String getName() { 14         return name; 15  } 16     public void setName(String name) { 17         this.name = name; 18  } 19     public int getAge() { 20         return age; 21  } 22     public void setAge(int age) { 23         this.age = age; 24  } 25     public String getAddress() { 26         return address; 27  } 28     public void setAddress(String address) { 29         this.address = address; 30  } 31     
32     public Object clone() throws CloneNotSupportedException{ 33         return (Company)super.clone(); 34  } 35     
36  @Override 37     public String toString() { 38         return "Company [name=" + name + ", age=" + age + ", address=" + address + "]"; 39  } 40 }
程序運行結果:
1 false
2 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 3 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 4 
5 Person [name=張三, age=23, com=Company [name=alibaba, age=3, address=杭州]] 6 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 7 
8 Person [name=張三, age=23, com=Company [name=alibaba, age=3, address=杭州]] 9 Person [name=張三, age=23, com=Company [name=baidu, age=4, address=北京]
根據思路B我們可以得到兩個相互獨立的對象.
但是,又產生了新的問題:
若是在com中還有類似於Company的對象存在呢(內部還有很多屬性和方法)?
若是在Person中也有很多類似於Company的對象存在呢?
若是繼續采用思路B,寫起來會非常麻煩,並且有可能會遺漏(某個對象也許沒有被克隆的情況).
針對產生的新的問題,我們需要重新思考解決方案:思路C
  ①:Person, Company實現Serializable接口.
  ②:采用對象流創建Person對象.
根據思路C編寫程序:
 1 import java.io.ByteArrayInputStream;  2 import java.io.ByteArrayOutputStream;  3 import java.io.IOException;  4 import java.io.ObjectInputStream;  5 import java.io.ObjectOutputStream;  6 import java.io.Serializable;  7 
 8 
 9 public class Person implements Serializable{ 10     
11     public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException { 12         // 測試 13         //1.創建原型對象
14         Company com = new Company("tencent", 5, "深圳"); 15         Person person = new Person("張三", 23, com); 16         //原型克隆
17         Person copyPerson = person.getCopyPerson(); 18         System.out.println(person == copyPerson); 19  System.out.println(person); 20  System.out.println(copyPerson); 21         
22         //2.person改變com的值
23         Company personCom = person.getCom(); 24         personCom.setName("alibaba"); 25         personCom.setAge(5); 26         personCom.setAddress("杭州"); 27  System.out.println(person); 28  System.out.println(copyPerson); 29         
30         //3.copyPerson改變com的值
31         Company copyPersonCom = copyPerson.getCom(); 32         copyPersonCom.setName("baidu"); 33         copyPersonCom.setAge(3); 34         copyPersonCom.setAddress("北京"); 35  System.out.println(person); 36  System.out.println(copyPerson); 37  } 38 
39     private String name; 40     private int age; 41     private Company com; 42     
43     public Person() {} 44     
45     public Person(String name, int age, Company com) { 46         this.name = name; 47         this.age = age; 48         this.com = com; 49  } 50     
51     public String getName() { 52         return name; 53  } 54     public void setName(String name) { 55         this.name = name; 56  } 57     public int getAge() { 58         return age; 59  } 60     public void setAge(int age) { 61         this.age = age; 62  } 63     public Company getCom() { 64         return com; 65  } 66 
67     public void setCom(Company com) { 68         this.com = com; 69  } 70     
71  @Override 72     public String toString() { 73         return "Person [name=" + name + ", age=" + age + ", com=" + com + "]"; 74  } 75     
76     public Person getCopyPerson() throws IOException, ClassNotFoundException { 77         // 創建輸出流
78         ByteArrayOutputStream bos = new ByteArrayOutputStream(); 79         ObjectOutputStream oos = new ObjectOutputStream(bos); 80         oos.writeObject(this); 81         
82         // 創建輸入流
83         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 84         ObjectInputStream ois = new ObjectInputStream(bis); 85         Object obj = ois.readObject(); 86         return (Person)obj; 87  } 88 }
 1 import java.io.Serializable;  2 
 3 public class Company implements Serializable{  4 
 5     private static final long serialVersionUID = 1L;  6     private String name;  7     private int age;  8     private String address;  9     public Company() { 10  } 11     public Company(String name, int age, String address) { 12         this.name = name; 13         this.age = age; 14         this.address = address; 15  } 16     public String getName() { 17         return name; 18  } 19     public void setName(String name) { 20         this.name = name; 21  } 22     public int getAge() { 23         return age; 24  } 25     public void setAge(int age) { 26         this.age = age; 27  } 28     public String getAddress() { 29         return address; 30  } 31     public void setAddress(String address) { 32         this.address = address; 33  } 34     
35  @Override 36     public String toString() { 37         return "Company [name=" + name + ", age=" + age + ", address=" + address + "]"; 38  } 39 }
程序運行結果:
1 false
2 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 3 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 4 
5 Person [name=張三, age=23, com=Company [name=alibaba, age=5, address=杭州]] 6 Person [name=張三, age=23, com=Company [name=tencent, age=5, address=深圳]] 7 
8 Person [name=張三, age=23, com=Company [name=alibaba, age=5, address=杭州]] 9 Person [name=張三, age=23, com=Company [name=baidu, age=3, address=北京]]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM