Java中的深复制和浅复制

时间:2022-08-23 13:12:28

1. 浅复制:只复制了对象的引用,实际对应的还是一个对象实例,例如下例中的Address

 1 /*
 2  * 浅复制
 3  */
 4 
 5 class Address2  {  
 6     private String add;  
 7   
 8     public String getAdd() {  
 9         return add;  
10     }  
11   
12     public void setAdd(String add) {  
13         this.add = add;  
14     }  
15       
16 }  
17   
18 class Student2 implements Cloneable{  
19     private int number;  
20   
21     private Address2 addr;  
22       
23     public Address2 getAddr() {  
24         return addr;  
25     }  
26   
27     public void setAddr(Address2 addr) {  
28         this.addr = addr;  
29     }  
30   
31     public int getNumber() {  
32         return number;  
33     }  
34   
35     public void setNumber(int number) {  
36         this.number = number;  
37     }  
38       
39     @Override  
40     public Object clone() {  
41         Student2 stu = null;  
42         try{  
43             stu = (Student2)super.clone();  
44         }catch(CloneNotSupportedException e) {  
45             e.printStackTrace();  
46         }  
47         return stu;  
48     }  
49 }  
50 public class CopyTest2 {  
51       
52     public static void main(String args[]) {  
53           
54         Address2 addr = new Address2();  
55         addr.setAdd("杭州市");  
56         Student2 stu1 = new Student2();  
57         stu1.setNumber(123);  
58         stu1.setAddr(addr);  
59           
60         Student2 stu2 = (Student2)stu1.clone();  
61           
62         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
63         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
64         addr.setAdd("合肥市");
65         stu1.setAddr(addr);
66         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
67         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
68     }  
69 } 

 

2. 深复制:复制另一个实例对象,两者没有任何交叉的关系

 1 /*
 2  * 深复制
 3  */
 4 class Address implements Cloneable {  
 5     private String add;  
 6   
 7     public String getAdd() {  
 8         return add;  
 9     }  
10   
11     public void setAdd(String add) {  
12         this.add = add;  
13     }  
14       
15     @Override  
16     public Object clone() {  
17         Address addr = null;  
18         try{  
19             addr = (Address)super.clone();  
20         }catch(CloneNotSupportedException e) {  
21             e.printStackTrace();  
22         }  
23         return addr;  
24     }  
25 }  
26   
27 class Student implements Cloneable{  
28     private int number;  
29   
30     private Address addr;  
31       
32     public Address getAddr() {  
33         return addr;  
34     }  
35   
36     public void setAddr(Address addr) {  
37         this.addr = addr;  
38     }  
39   
40     public int getNumber() {  
41         return number;  
42     }  
43   
44     public void setNumber(int number) {  
45         this.number = number;  
46     }  
47       
48     @Override  
49     public Object clone() {  
50         Student stu = null;  
51         try{  
52             stu = (Student)super.clone();   //浅复制  
53         }catch(CloneNotSupportedException e) {  
54             e.printStackTrace();  
55         }  
56         stu.addr = (Address)addr.clone();   //深度复制  
57         return stu;  
58     }  
59 }  
60 public class CopyTest {  
61       
62     public static void main(String args[]) {  
63           
64         Address addr = new Address();  
65         addr.setAdd("杭州市");  
66         Student stu1 = new Student();  
67         stu1.setNumber(123);  
68         stu1.setAddr(addr);  
69           
70         Student stu2 = (Student)stu1.clone();  
71           
72         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
73         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
74           
75         addr.setAdd("西湖区");  
76           
77         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
78         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
79     }  
80 }

3. 观察两者的区别不难发现,只一点浅复制的Address类没有继承Cloneable接口,进而实现clone()方法。默认的是java.lang.Object的clone()方法。

4. 对象的序列化也能实现深复制。但需要对象中的每一种成分都是可序列化的才行。

5. Java中参数传递:值传递和引用传递的简单总结

  • 对象就是传引用
  • 原始类型就是传值
  • String类型因为没有提供自身修改的函数,每次操作都是新生成一个String对象,所以要特殊对待。可以认为是传值。