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