=、浅拷贝和深拷贝的区分

 1 package copy_types;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 /**
 7  * '=' symbol copy
 8  * @author ASUS
 9  *
10  */
11 
12 class ClassA{
13     int a = 1;//值类型
14     
15     List<String> list;//引用类型
16     
17     public ClassA(){
18         list = new ArrayList<>();
19         list.add("string 1");
20         list.add("string 2");
21     }
22     
23     public void print(){
24         System.out.println("-----"+this.toString()+"-----");
25         System.out.println("a = " + a);
26         System.out.println("list = " + list);
27     }
28     
29     public void change(){
30         this.a = 2;
31         this.list.clear();
32     }
33 }
34 
35 public class EqualSymbol {
36     public static void main(String args[]){
37         ClassA A = new ClassA();
38         ClassA B = A;
39         
40         A.print();
41         B.print();
42         
43         B.change();
44         
45         A.print();
46         B.print();
47     }
48 }

打印结果:

-----copy_types.ClassA@327800e9-----
a = 1
list = [string 1, string 2]
-----copy_types.ClassA@327800e9-----
a = 1
list = [string 1, string 2]
-----copy_types.ClassA@327800e9----- a = 2 list = [] -----copy_types.ClassA@327800e9----- a = 2 list = []

从结果可以看出经过等号“=”复制之后,他们所指向的都是一个对象,所以不管类里面的对象是值类型还是引用类型,一旦修改,处处修改。

 

浅拷贝:

 1 package copy_types;
 2 
 3 /**
 4  * 自定义一个类(作为自定义的引用类型的测试)
 5  * @author ASUS
 6  *
 7  */
 8 public class CommonClass {
 9     
10     int a = 1;
11 
12     public int getA() {
13         return a;
14     }
15 
16     public void setA(int a) {
17         this.a = a;
18     }
19 
20 }
package copy_types;

import java.util.ArrayList;
import java.util.List;

/**
 * 浅拷贝
 * @author ASUS
 *
 */

class ClassB implements Cloneable{
	int a = 1;//值类型
	
	String str;
	List<String> list;//引用类型
	CommonClass cc;
	
	public ClassB(){
		list = new ArrayList<>();
		list.add("string 1");
		list.add("string 2");
		str = "str1";
		cc = new CommonClass();
	}
	
	public void print(){
		System.out.println("-----"+this.toString()+"-----");
		System.out.println("a = " + a);
		System.out.println("str = " + str);
		System.out.println("list = " + list);
		System.out.println("cc = " + cc.getA());
		
	}
	
	public void change(){
		this.a = 2;
		this.list.clear();
		this.str = "str2";
		cc.setA(100);
	}
	
	@Override
	protected Object clone() {
		// TODO Auto-generated method stub
		Object o = null;
		try {
			o = super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return o;
	}
}
public class ShallowCopy {
	public static void main(String args[]){
		ClassB b = new ClassB();
		
		ClassB changeB = (ClassB) b.clone();
		changeB.change();
		
		b.print();
		changeB.print();
	}
}

  结果:

-----copy_types.ClassB@44cae5b8-----
a = 1
str = str1
list = []
cc = 100
-----copy_types.ClassB@17823918-----
a = 2
str = str2
list = []
cc = 100

由此可以看出b和changeB指向的是不通地址的对象,此时各自的值类型各自拥有,值类型的修改互相不影响,但是,里面的引用类型的仍然指向同一个对象,一个修改,处处修改。例如上面的cc中的值类型a被修改成了100,而由于b对象的cc和changeB对象的cc指向的是同一个对象,那么既然changeB中的cc.a被修改了,b.cc.a也同样改变了。

 

深拷贝:

简单做个说明,深拷贝时从浅拷贝引发的,浅拷贝只是一层的clone,而深拷贝要对类中的引用类型进行clone,比如让CommonClass实现Cloneable接口,并且实现clone接口,在原来的类中调用clone来复制对象。请看代码:

 1 package copy_types;
 2 
 3 class CClass implements Cloneable{
 4     
 5     int a = 0;
 6     
 7     public int getA() {
 8         return a;
 9     }
10 
11     public void setA(int a) {
12         this.a = a;
13     }
14 
15     @Override
16     protected Object clone()  {
17         // TODO Auto-generated method stub
18         Object o = null;
19         try {
20             o =  super.clone();
21         } catch (CloneNotSupportedException e) {
22             // TODO Auto-generated catch block
23             e.printStackTrace();
24         }
25         return o;
26     }
27 }
28 
29 class DeepCopy implements Cloneable{
30     CClass dc;
31     public DeepCopy(){
32         dc = new CClass();
33     }
34     
35     public void print(){
36         System.out.println(dc.toString()+"\n"+dc.getA());
37     }
38     
39     public void change(){
40         dc.setA(1000);
41     }
42     
43     @Override
44     protected Object clone() {
45         // TODO Auto-generated method stub
46         DeepCopy o = null;
47         try {
48             o = (DeepCopy) super.clone();
49             o.dc = (CClass) dc.clone();
50         } catch (CloneNotSupportedException e) {
51             // TODO Auto-generated catch block
52             e.printStackTrace();
53         }
54         return o;
55     }
56 }
57 
58 public class DeepClone {
59     
60     public static void main(String args[]){
61         DeepCopy d = new DeepCopy();
62         DeepCopy e = (DeepCopy) d.clone();
63         
64         e.change();
65         
66         d.print();
67         e.print();
68     }
69 
70 }

输出:

copy_types.CClass@397b6178
0
copy_types.CClass@533c2ac3
1000

由此可以看出里面的引用类型对象属于不同的对象,一个修改不影响另一个,简而言之,深拷贝就是要将浅拷贝“进行到底”。

posted @ 2013-10-27 01:29  我是一颗小草  阅读(147)  评论(0编辑  收藏  举报