一、對象的淺克隆
(1)需要克隆類需要重寫Object類的clone方法,并且實現Cloneable接口(標識接口,無需實現任何方法)
(2)當需要克隆的對象中維護著另外一個引用對象,淺克隆不會克隆另外一個引用對下,而是直接復制維護的另外一個引用對象的地址。
(3)對象的淺克隆也不會調用到構造方法。
以下為對象的淺克隆的一個例子:
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: * 實現了Cloneable接口,并重寫Object類的clone方法。 * * @author lee * */ public class CloneDemo1 implements Cloneable,Serializable{ //該克隆類封裝的信息 public int id; public String name; public Address address; /** * Desciption: * 默認構造器 * * */ public CloneDemo1(){} /** * Description: * 初始化id,name的構造器 * * @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 復制了c1的地址,并沒有復制整個c1對象 CloneDemo1 c2 = c1; //c3 對象的淺克隆,復制了整個對象 CloneDemo1 c3 = (CloneDemo1)c1.clone(); //當對象c1改變其name或者id的時候,c2也會自動改變。 //因為c2只是復制了c1的地址,并非復制了c1的整個對象。 //相應的c3則不會隨著c1改變而改變,意味著c3將c1整個對象克隆一份出來。 //當是,對象的淺克隆不會克隆被克隆對象當中的引用對象。 //因此c1改變其中的Address的引用對象時,c2,c3也會跟著改變。 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: * 一個封裝著地址的類 * * @author lee * */ class Address implements Serializable{ public String address; /** * Description: * 默認構造器 * * */ 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; } } |
二、對象的深克隆
就是利用對象的輸入輸出流把對象寫到文件上,再讀取對象的信息,這就是對象的深克隆。
由于對象的淺克隆不會克隆被克隆對象其中的引用對象,而是直接復制其地址。因此,要克隆被克隆對象當中的引用類型則需要對象的深克隆。
而對象的深克隆使用的的對象序列化輸入輸出。
代碼如下:
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: * 實現對象的深克隆 * * @author lee * */ public class CloneDemo2 { /** * Description: * 將對象輸出到一個文件當中。 * * @param c 需要被寫到文件當中的對象。 * */ public static void writeObject(CloneDemo1 c){ ObjectOutputStream out = null ; try { //將對象輸出在一個object.txt文件當中 out = new ObjectOutputStream( new FileOutputStream( "./object.txt" )); out.writeObject(c); } catch (IOException e){ System.out.println( "寫入對象的時候發生了錯誤。" ); e.printStackTrace(); } finally { //關閉資源 try { out.close(); } catch (IOException e){ e.printStackTrace(); } } } /** * Description: * 從文件中讀取出一個對象來,并返回。 * * @return c 返回一個對象。 * */ public static CloneDemo1 readObject(){ CloneDemo1 c = null ; ObjectInputStream input = null ; try { //從object.txt文件中讀取一個對象出來 input = new ObjectInputStream( new FileInputStream( "./object.txt" )); c = (CloneDemo1)input.readObject(); } catch (IOException | ClassNotFoundException e){ e.printStackTrace(); System.out.println( "讀取對象的時候發生了錯誤。" ); } finally { //關閉資源 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 對象的淺克隆 CloneDemo1 c2 = (CloneDemo1)c1.clone(); //c3對象的深克隆 writeObject(c1); CloneDemo1 c3 = readObject(); //因為對象的深克隆同時也克隆了被克隆對象維護的另外一個對象 //所以,當c1改變其當中的維護的另外一個對象的時候,c3不會隨之改變。 //而c2位淺克隆,其維護的另外一個對象只是復制了c1維護的對象的地址,因此會隨著c1的改變而改變。 c1.address.setAddress( "上海" ); System.out.println(c1+ "\n" +c2+ "\n" +c3); } } |
對象的序列化,是需要實現Serializable接口的。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://blog.csdn.net/qq1131410679/article/details/65934698