欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

复制对象与复制引用

程序员文章站 2022-04-29 17:51:54
原型模式:(复制对象) 1.复制"引用"与复制"对象"的区别 1.1复制"引用"---复制地址 假设被复制对象为A a,复制的新对象为A b. 复制引用的过程就是将a的地址值复制给b.a和b同时指向堆内存的同一个地址. 过程为: 1 A a = new A(); 2 A b = a; 这样,只要其中... ......
原型模式:(复制对象)
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=北京]]