先用一个例子来说明假克隆吧,也就是用“=”之后的效果、。
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接口。其次,如果这个类的域中也有引用对象,则也有要求这个引用类型也实现这个接口,。最后,序列化方式实现克隆效率不高,没有直接深度克隆的效率高。