一、對(duì)象的淺克隆
(1)需要克隆類需要重寫Object類的clone方法,并且實(shí)現(xiàn)Cloneable接口(標(biāo)識(shí)接口,無需實(shí)現(xiàn)任何方法)
(2)當(dāng)需要克隆的對(duì)象中維護(hù)著另外一個(gè)引用對(duì)象,淺克隆不會(huì)克隆另外一個(gè)引用對(duì)下,而是直接復(fù)制維護(hù)的另外一個(gè)引用對(duì)象的地址。
(3)對(duì)象的淺克隆也不會(huì)調(diào)用到構(gòu)造方法。
以下為對(duì)象的淺克隆的一個(gè)例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
package com.clone; import java.io.Serializable; /** * Description: * 實(shí)現(xiàn)了Cloneable接口,并重寫Object類的clone方法。 * * @author lee * */ public class CloneDemo1 implements Cloneable,Serializable{ //該克隆類封裝的信息 public int id; public String name; public Address address; /** * Desciption: * 默認(rèn)構(gòu)造器 * * */ public CloneDemo1(){} /** * Description: * 初始化id,name的構(gòu)造器 * * @param id id * @param name 名字 * @param address 地址 * */ public CloneDemo1( int id, String name, Address address){ this .id=id; this .name=name; this .address = address; } /** * Descriptin: * 重寫Object類的clone方法。 * if the object's class does not support the Cloneable interface. * Subclasses that override the clone method can also throw this exception * to indicate that an instance cannot be cloned. * * @throws CloneNotSupportedException * */ @Override public Object clone() throws CloneNotSupportedException{ return super .clone(); } /** * Description: * 重寫toString方法 * * @return "id="+id+", name="+name * */ @Override public String toString(){ return "id=" +id+ ", name=" +name+ ", address:" +address.getAddress(); } /** * Description: * 主方法 * * */ public static void main(String[] args) throws CloneNotSupportedException{ CloneDemo1 c1 = new CloneDemo1( 1 , "c1" , new Address( "北京" )); //c2 復(fù)制了c1的地址,并沒有復(fù)制整個(gè)c1對(duì)象 CloneDemo1 c2 = c1; //c3 對(duì)象的淺克隆,復(fù)制了整個(gè)對(duì)象 CloneDemo1 c3 = (CloneDemo1)c1.clone(); //當(dāng)對(duì)象c1改變其name或者id的時(shí)候,c2也會(huì)自動(dòng)改變。 //因?yàn)閏2只是復(fù)制了c1的地址,并非復(fù)制了c1的整個(gè)對(duì)象。 //相應(yīng)的c3則不會(huì)隨著c1改變而改變,意味著c3將c1整個(gè)對(duì)象克隆一份出來。 //當(dāng)是,對(duì)象的淺克隆不會(huì)克隆被克隆對(duì)象當(dāng)中的引用對(duì)象。 //因此c1改變其中的Address的引用對(duì)象時(shí),c2,c3也會(huì)跟著改變。 c1.setName( "cc" ); c1.address.setAddress( "上海" ); System.out.println(c1+ "\n" +c2+ "\n" +c3); } public int getId() { return id; } public void setId( int id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } } /** * Description: * 一個(gè)封裝著地址的類 * * @author lee * */ class Address implements Serializable{ public String address; /** * Description: * 默認(rèn)構(gòu)造器 * * */ public Address(){} /** * Description: * 初試化address * * @param address 地址 * */ public Address(String address){ this .address = address; } //address的set和get方法 public String getAddress() { return address; } public void setAddress(String address) { this .address = address; } } |
二、對(duì)象的深克隆
就是利用對(duì)象的輸入輸出流把對(duì)象寫到文件上,再讀取對(duì)象的信息,這就是對(duì)象的深克隆。
由于對(duì)象的淺克隆不會(huì)克隆被克隆對(duì)象其中的引用對(duì)象,而是直接復(fù)制其地址。因此,要克隆被克隆對(duì)象當(dāng)中的引用類型則需要對(duì)象的深克隆。
而對(duì)象的深克隆使用的的對(duì)象序列化輸入輸出。
代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
package com.clone; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * Description: * 實(shí)現(xiàn)對(duì)象的深克隆 * * @author lee * */ public class CloneDemo2 { /** * Description: * 將對(duì)象輸出到一個(gè)文件當(dāng)中。 * * @param c 需要被寫到文件當(dāng)中的對(duì)象。 * */ public static void writeObject(CloneDemo1 c){ ObjectOutputStream out = null ; try { //將對(duì)象輸出在一個(gè)object.txt文件當(dāng)中 out = new ObjectOutputStream( new FileOutputStream( "./object.txt" )); out.writeObject(c); } catch (IOException e){ System.out.println( "寫入對(duì)象的時(shí)候發(fā)生了錯(cuò)誤。" ); e.printStackTrace(); } finally { //關(guān)閉資源 try { out.close(); } catch (IOException e){ e.printStackTrace(); } } } /** * Description: * 從文件中讀取出一個(gè)對(duì)象來,并返回。 * * @return c 返回一個(gè)對(duì)象。 * */ public static CloneDemo1 readObject(){ CloneDemo1 c = null ; ObjectInputStream input = null ; try { //從object.txt文件中讀取一個(gè)對(duì)象出來 input = new ObjectInputStream( new FileInputStream( "./object.txt" )); c = (CloneDemo1)input.readObject(); } catch (IOException | ClassNotFoundException e){ e.printStackTrace(); System.out.println( "讀取對(duì)象的時(shí)候發(fā)生了錯(cuò)誤。" ); } finally { //關(guān)閉資源 try { input.close(); } catch (IOException e){ e.printStackTrace(); } } return c; } /** * Description: * 主方法 * * @throws CloneNotSupportedException * */ public static void main(String[] args) throws CloneNotSupportedException { CloneDemo1 c1 = new CloneDemo1( 1 , "c1" , new Address( "北京" )); //c2 對(duì)象的淺克隆 CloneDemo1 c2 = (CloneDemo1)c1.clone(); //c3對(duì)象的深克隆 writeObject(c1); CloneDemo1 c3 = readObject(); //因?yàn)閷?duì)象的深克隆同時(shí)也克隆了被克隆對(duì)象維護(hù)的另外一個(gè)對(duì)象 //所以,當(dāng)c1改變其當(dāng)中的維護(hù)的另外一個(gè)對(duì)象的時(shí)候,c3不會(huì)隨之改變。 //而c2位淺克隆,其維護(hù)的另外一個(gè)對(duì)象只是復(fù)制了c1維護(hù)的對(duì)象的地址,因此會(huì)隨著c1的改變而改變。 c1.address.setAddress( "上海" ); System.out.println(c1+ "\n" +c2+ "\n" +c3); } } |
對(duì)象的序列化,是需要實(shí)現(xiàn)Serializable接口的。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
原文鏈接:http://blog.csdn.net/qq1131410679/article/details/65934698