先用一個例子來說明假克隆吧,也就是用“=”之後的效果、。
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
|
public class Employee{ public Employee(){ } public Employee(String name, int
age){ this .age = age; this .name = name; } @Override public String toString(){ return "姓名: " + name + "年齡: "
+ age; } public String getName(){ return name; } public void setName(String name){ this .name = name; } public int getAge(){ return age; } public void setAge( int
age){ this .age = age; } public static void main(String[] args){ Employee demo1 = new Employee( "rollen" ,
20 ); System.out.println(demo1); Employee demo2 = demo1; demo2.setAge( 100 ); demo2.setName( "hello world" ); System.out.println(demo1); System.out.println(demo2); } private String name; private int age; } |
【運行結果】:
【運行結果】
姓名: rollen年齡: 20
姓名: hello world年齡: 100
姓名: hello world年齡: 100
下面看看java中的淺拷貝
對於類中的每個域,如果只包含基本類型或者不可變的引用類型,如String,或者對象在其生命週期內不會發生變化,則可以使用淺拷貝來複制對象,但是一般使用深拷貝。
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
|
class Address{ public Address(){ } public Address(String state, int
number){ this .number = number; this .state = state; } @Override public String toString(){ return "state: " + state + " munber: "
+ number; } public String getState(){ return state; } public void setState(String state){ this .state = state; } public int getNumber(){ return number; } public void setNumber( int
number){ this .number = number; } private String state; private int number; } public class Employee implements
Cloneable{ public Employee(){ } public Employee(String name, int
age, Address address){ this .address = address; this .age = age; this .name = name; } public String getName(){ return name; } public void setName(String name){ this .name = name; } public int getAge(){ return age; } public void setAge( int
age){ this .age = age; } public Address getAddress(){ return address; } public void setAddress(Address address){ this .address = address; } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append( "name:" + name + ", " ); sb.append( "age:" + age + " \n" ); sb.append( "Address: " + address); return sb.toString(); } @Override protected Employee clone(){ Employee employee = null ; try { employee = (Employee) super .clone(); } catch (CloneNotSupportedException e){ e.printStackTrace(); } return employee; } public static void main(String[] args){ System.out.println( "克隆之前:" ); Address add1 = new Address( "中國" ,
1 ); Employee emp1 = new Employee( "rollen" ,
20 , add1); System.out.println(emp1); System.out.println( "克隆之後" ); Employee emp2 = emp1.clone(); emp2.setName( "hello world" ); emp2.setAge( 100 ); emp2.address.setNumber( 2 ); emp2.address.setState( "美國" ); System.out.println(emp1); System.out.println( "-----" ); System.out.println(emp2); } private String name; private int age; private Address address; } |
【運行結果】:
克隆之前:
name:rollen, age:20
Address: state: 中國 munber: 1
克隆之後
name:rollen, age:20
Address: state: 美國 munber: 2
-----
name:hello world, age:100
Address: state: 美國 munber: 2
但是上面的主函數中的:
1
2
|
// emp2.address.setNumber(2); // emp2.address.setState("美國"); |
替換爲:
1
|
emp2.setAddress( new Address( "美國" ,
2 )); |
運行結果爲:
克隆之前:
name:rollen, age:20
Address: number: 1state中國
克隆之後
name:rollen, age:20
Address: number: 1state中國
-----
name:hello world, age:100
Address: number: 2state美國
這裏我有點不明白了,爲什麼這種情況下克隆之後兩個address會不一樣呢?
誰幫忙指點一下,謝謝了、
現在看看java對象的深克隆
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
|
class Address implements Cloneable{ public Address(){ } public Address(String state, int
number){ this .number = number; this .state = state; } @Override public String toString(){ return "state: " + state + " munber: "
+ number; } @Override protected Address clone() throws
CloneNotSupportedException{ Address address = null ; address = (Address) super .clone(); return address; } public String getState(){ return state; } public void setState(String state){ this .state = state; } public int getNumber(){ return number; } public void setNumber( int
number){ this .number = number; } private String state; private int number; } public class Employee implements
Cloneable{ public Employee(){ } public Employee(String name, int
age, Address address){ this .address = address; this .age = age; this .name = name; } public String getName(){ return name; } public void setName(String name){ this .name = name; } public int getAge(){ return age; } public void setAge( int
age){ this .age = age; } public Address getAddress(){ return address; } public void setAddress(Address address){ this .address = address; } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append( "name:" + name + ", " ); sb.append( "age:" + age + " \n" ); sb.append( "Address: " + address); return sb.toString(); } @Override protected Employee clone(){ Employee employee = null ; try { employee = (Employee) super .clone(); employee.address = address.clone(); } catch (CloneNotSupportedException e){ e.printStackTrace(); } return employee; } public static void main(String[] args){ System.out.println( "克隆之前:" ); Address add1 = new Address( "中國" ,
1 ); Employee emp1 = new Employee( "rollen" ,
20 , add1); System.out.println(emp1); System.out.println( "克隆之後" ); Employee emp2 = emp1.clone(); emp2.setName( "hello world" ); emp2.setAge( 100 ); emp2.setAddress( new Address( "美國" ,
2 )); System.out.println(emp1); System.out.println( "-----" ); System.out.println(emp2); } private String name; private int age; private Address address; } |
【運行結果】:
【運行結果】:
克隆之前:
name:rollen, age:20
Address: state: 中國 munber: 1
克隆之後
name:rollen, age:20
Address: state: 中國 munber: 1
-----
name:hello world, age:100
Address: state: 美國 munber: 2
序列化接口和對象克隆
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
|
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class Address implements Serializable{ public Address(){ } public Address(String state, int
number){ this .number = number; this .state = state; } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append( "number: " + number); sb.append( "state" + state + "\n" ); return sb.toString(); } public String getState(){ return state; } public void setState(String state){ this .state = state; } public int getNumber(){ return number; } public void setNumber( int
number){ this .number = number; } private String state; private int number; } public class Employee implements
Cloneable, Serializable{ public Employee(){ } public Employee(String name, int
age, Address address){ this .address = address; this .age = age; this .name = name; } public String getName(){ return name; } public void setName(String name){ this .name = name; } public int getAge(){ return age; } public void setAge( int
age){ this .age = age; } public Address getAddress(){ return address; } public void setAddress(Address address){ this .address = address; } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append( "name:" + name + ", " ); sb.append( "age:" + age + " \n" ); sb.append( "Address: " + address); return sb.toString(); } @Override protected Employee clone(){ Employee employee = null ; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject( this ); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); employee = (Employee) ois.readObject(); ois.close(); } catch (Exception e){ e.printStackTrace(); } return employee; } public static void main(String[] args){ System.out.println( "克隆之前:" ); Address add1 = new Address( "中國" ,
1 ); Employee emp1 = new Employee( "rollen" ,
20 , add1); System.out.println(emp1); System.out.println( "克隆之後" ); Employee emp2 = emp1.clone(); emp2.setName( "hello world" ); emp2.setAge( 100 ); emp2.address.setNumber( 2 ); emp2.address.setState( "美國" ); System.out.println(emp1); System.out.println( "-----" ); System.out.println(emp2); } private String name; private int age; private Address address; } |
【運行結果】:
克隆之前:
name:rollen, age:20
Address: number: 1state中國
克隆之後
name:rollen, age:20
Address: number: 1state中國
-----
name:hello world, age:100
Address: number: 2state美國
對於任何一個序列化的對象,都必須要求實現Serializable接口。其次,如果這個類的域中也有引用對象,則也有要求這個引用類型也實現這個接口,。最後,序列化方式實現克隆效率不高,沒有直接深度克隆的效率高。