java中的深淺複製

Java深度複製和淺度複製
淺複製(淺克隆):淺複製僅僅複製所考慮的對象,而不復制它所引用的對象。
深複製(深克隆):深複製把要複製的對象所引用的對象都複製了一遍。
Java中對象的克隆,爲了獲取對象的一份拷貝,我們可以利用Object類的clone()方法。必須要遵循下面三點 :
1.在派生類中覆蓋基類的clone()方法,並聲明爲public【Object類中的clone()方法爲protected的】。
2.在派生類的clone()方法中,調用super.clone()。
3.在派生類中實現Cloneable接口。

Object類裏的clone方法是淺複製(淺克隆)

淺複製(淺克隆)的例子如下:
package com.test;

1.public class DeepCloneTest {  
2. public static void main(String[] args) throws Exception{  
3.  //teacher對象將不被clone出來的Student對象共享.  
4.  Teacher teacher = new Teacher();  
5.  teacher.setAge(40);  
6.  teacher.setName("Teacher zhang");  
7.    
8.  Student student1 = new Student();  
9.  student1.setAge(20);  
10.  student1.setName("zhangsan");  
11.  student1.setTeacher(teacher);  
13.//複製出來一個對象student2  
14.  Student student2 = (Student)student1.clone();  
15.  System.out.println(student2.getAge());  
16.  System.out.println(student2.getName());  
17.    
18.    
19.  System.out.println("~~~~~~~~~~~~~~~~~~~~~~");  
20.  System.out.println(student1.getTeacher().getAge());  
21.  System.out.println(student1.getTeacher().getName());  
22.    
23.    
24.  //修改student2的引用對象  
25.  student2.getTeacher().setAge(50);  
26.  student2.getTeacher().setName("Teacher Li");  
27.    
28.  System.out.println("~~~~~~~~~~~~~~~~~~~~~~");  
29.  System.out.println(student1.getTeacher().getAge());  
30.  System.out.println(student1.getTeacher().getName());  
31. }  
32.}  
1.class Teacher {  
2. public int age;  
3. public String name;  
4.   
5. public int getAge() {  
6.  return age;  
7. }  
8. public void setAge(int age) {  
9.  this.age = age;  
10. }  
11. public String getName() {  
12.  return name;  
13. }  
14. public void setName(String name) {  
15.  this.name = name;  
16. }  

輸出結果爲:
20
zhangsan
~~~~~~~~~~~~~~~~~~
40
Teacher zhang
~~~~~~~~~~~~~~~~~~
50
Teacher Li
2.深複製(深Clone)例子:

1.package com.test1;  
2.//深clone  
3.public class DeepCloneTest {  
4. public static void main(String[] args) throws Exception{  
5.  //teacher對象將不被clone出來的Student對象共享.  
6.  Teacher teacher = new Teacher();  
7.  teacher.setAge(40);  
8.  teacher.setName("Teacher zhang");  
9.    
10.  Student student1 = new Student();  
11.  student1.setAge(20);  
12.  student1.setName("zhangsan");  
13.  student1.setTeacher(teacher);  
14.    
15.  //複製出來一個對象student2  
16.  Student student2 = (Student)student1.clone();  
17.  System.out.println(student2.getAge());  
18.  System.out.println(student2.getName());  
19.    
20.    
21.  System.out.println("~~~~~~~~~~~~~~~~~~~~~~");  
22.  System.out.println(student1.getTeacher().getAge());  
23.  System.out.println(student1.getTeacher().getName());  
24.    
25.    
26.  //修改student2的引用對象  
27.  student2.getTeacher().setAge(50);  
28.  student2.getTeacher().setName("Teacher Li");  
29.    
30.  System.out.println("~~~~~~~~~~~~~~~~~~~~~~");  
31.  System.out.println(student1.getTeacher().getAge());  
32.  System.out.println(student1.getTeacher().getName());  
33. }  
34.}  
35.class Teacher implements Cloneable{  
36. public int age;  
37. public String name;  
38.   
39. public int getAge() {  
40.  return age;  
41. }  
42. public void setAge(int age) {  
43.  this.age = age;  
44. }  
45. public String getName() {  
46.  return name;  
47. }  
48. public void setName(String name) {  
49.  this.name = name;  
50. }  
51. @Override  
52. public Object clone() throws CloneNotSupportedException {  
53.  return super.clone();  
54. }  
55.   
56.}  
57.class Student implements Cloneable{  
58.   
59. public int age ;  
60. public String name;  
61. public Teacher teacher;  
62. public int getAge() {  
63.  return age;  
64. }  
65. public void setAge(int age) {  
66.  this.age = age;  
67. }  
68. public String getName() {  
69.  return name;  
70. }  
71. public void setName(String name) {  
72.  this.name = name;  
73. }  
74. public Teacher getTeacher() {  
75.  return teacher;  
76. }  
77. public void setTeacher(Teacher teacher) {  
78.  this.teacher = teacher;  
79. }  
80. @Override  
81. public Object clone() throws CloneNotSupportedException {  
82.  Student student = (Student)super.clone();  
83.  //將引用的對象teacher也clone下  
84.  student.setTeacher((Teacher)(student.getTeacher().clone()));  
85.  return student;  
86. }  
87.   
88.   
89.}  

輸出結果爲:
20
zhangsan
~~~~~~~~~~~~~~~~~~
40
Teacher zhang
~~~~~~~~~~~~~~~~~~
40
Teacher zhang


## 利用序列化來做深複製,##
  把對象寫到流裏的過程是序列化(Serilization)過程,而把對象從流中讀出來的過程則叫做反序列化(Deserialization)過程。應當指出的是,寫在流裏的是對象的一個拷貝,而原對象仍然存在於JVM裏面。利用這個特性,可以做深拷貝。
1.package com.test3;  
2.import java.io.ByteArrayInputStream;  
3.import java.io.ByteArrayOutputStream;  
4.import java.io.ObjectInputStream;  
5.import java.io.ObjectOutputStream;  
6.import java.io.Serializable;  
7.//利用序列化來做深複製  
8.//深clone  
9.public class DeepCloneTest {  
10. public static void main(String[] args) throws Exception{  
11.  //teacher對象將不被clone出來的Student對象共享.  
12.  Teacher teacher = new Teacher();  
13.  teacher.setAge(40);  
14.  teacher.setName("Teacher zhang");  
15.    
16.  Student student1 = new Student();  
17.  student1.setAge(20);  
18.  student1.setName("zhangsan");  
19.  student1.setTeacher(teacher);  
20.    
21.  //複製出來一個對象student2  
22.  Student student2 = (Student)student1.deepCopy();  
23.  System.out.println(student2.getAge());  
24.  System.out.println(student2.getName());  
25.    
26.    
27.  System.out.println("~~~~~~~~~~~~~~~~~~~~~~");  
28.  System.out.println(student1.getTeacher().getAge());  
29.  System.out.println(student1.getTeacher().getName());  
30.    
31.    
32.  //修改student2的引用對象  
33.  student2.getTeacher().setAge(50);  
34.  student2.getTeacher().setName("Teacher Li");  
35.    
36.  System.out.println("~~~~~~~~~~~~~~~~~~~~~~");  
37.  System.out.println(student1.getTeacher().getAge());  
38.  System.out.println(student1.getTeacher().getName());  
39. }  
40.}  
41.class Teacher implements Serializable{  
42.   
43. private static final long serialVersionUID = -8834559347461591191L;  
44.   
45. public int age;  
46. public String name;  
47.   
48. public int getAge() {  
49.  return age;  
50. }  
51. public void setAge(int age) {  
52.  this.age = age;  
53. }  
54. public String getName() {  
55.  return name;  
56. }  
57. public void setName(String name) {  
58.  this.name = name;  
59. }  
60.   
61.}  
62.class Student implements Serializable{  
63.   
64. //serialVersionUID 如果你的對象序列化後存到硬盤上面後,可是後來你卻更改了類的field(增加或減少或改名),當你反序列化時,就會出現Exception的,這樣就會造成不兼容性的問題。   
65. //但當serialVersionUID相同時,它就會將不一樣的field以type的缺省值賦值(如int型的是0,String型的是null等),這個可以避開不兼容性的問題。所以最好給serialVersionUID賦值  
66. private static final long serialVersionUID = 7991552226614088458L;  
67.   
68. public int age ;  
69. public String name;  
70. public Teacher teacher;  
71. public int getAge() {  
72.  return age;  
73. }  
74. public void setAge(int age) {  
75.  this.age = age;  
76. }  
77. public String getName() {  
78.  return name;  
79. }  
80. public void setName(String name) {  
81.  this.name = name;  
82. }  
83. public Teacher getTeacher() {  
84.  return teacher;  
85. }  
86. public void setTeacher(Teacher teacher) {  
87.  this.teacher = teacher;  
88. }  
89.   
90. public Object deepCopy() throws Exception{  
91.  //將該對象序列化成流,因爲寫在流裏的是對象的一個拷貝,而原對象仍然存在於JVM裏面。所以利用這個特性可以實現對象的深拷貝  
92.  ByteArrayOutputStream bos = new ByteArrayOutputStream();  
93.  ObjectOutputStream oos = new ObjectOutputStream(bos);  
94.  oos.writeObject(this);  
95.  //將流序列化成對象  
96.  ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
97.  ObjectInputStream ois = new ObjectInputStream(bis);  
98.  return ois.readObject();  
99.  }    
102.}  

輸出結果爲:
20
zhangsan
~~~~~~~~~~~~~~~~~~
40
Teacher zhang
~~~~~~~~~~~~~~~~~~
40
Teacher zhang

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