当前位置: 移动技术网 > IT编程>开发语言>Java > 复制对象与复制引用

复制对象与复制引用

2019年06月12日  | 移动技术网IT编程  | 我要评论
原型模式:(复制对象)
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=北京]]

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网