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
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接口。其次,如果這個類的域中也有引用對象,則也有要求這個引用類型也實現這個接口,。最後,序列化方式實現克隆效率不高,沒有直接深度克隆的效率高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章