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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值