首先,先介绍一下java中的深拷贝以及浅拷贝,深浅拷贝都属于克隆,不同的是浅拷贝是指只对对象的基本类型进行一个简单的拷贝,而深拷贝是指对对象的所有属性进行拷贝,不论是基本类型还是引用类型。
为了让大家更深刻了解深浅拷贝,下面举例说明:
class CloneTest
{
public static void main(String[] args)
{
Manager m=new Manager("manager",50);
Programmer p1=new Programmer("tomison",18,m);
Programmer p2=(Programmer)st1.clone();
p2.name="jason";
p2.aa[0] = 10;
p2.m.name = "projectManager";
System.out.println(p1.name+" "+p2.name);
System.out.println(p1.m.name+" "+p2.m.name);
System.out.println(p1.aa[0]+" "+p2.aa[0]);
}
}
//要想对一个对象实现拷贝功能,必须实现Cloneable,重写clone()方法
class Manager implements Cloneable
{
String name;
int age;
Manager(String name,int age)
{
this.name=name;
this.age=age;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(toString());
}
return o;
}
}
class Programmer implements Cloneable
{
String name;
int age;
Manager m;
int[] aa = new int[3];
Programmer(String name,int age,Manager m)
{
this.name= new String(name);
this.age=age;
this.m=m;
this.aa[0]=1;
this.aa[1]=2;
this.aa[2]=3;
}
public Object clone()
{
Programmer o=null;
try
{
o=(Programmer)super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(toString());
}
//o.m=(Manager)o.m.clone();
//o.aa = (int[])o.aa.clone();
return o;
}
}
上面的运行结果如下:
tomison
Jason
projectManager
projectManager
10
10
从上面可以看出,Programmer类p1中的引用类型Manager以及数组aa随着p2值的改变而改变,基本类型name没有随着p2值的改变而改变,因为Programmer类只实现了浅拷贝,p1、p2引用类型属性的值指向的都是同一个内存地址,所以当p2中的引用属性的值更改时,相应p1的值也会更改,把以下两行注释去掉,看看运行的结果有何不同:
o.m=(Manager)o.m.clone();
o.aa = (int[])o.aa.clone();
这时的运行结果如下:
tomison
Jason
manager
projectManager
1
10
当去掉那两行注释后,Programmer这个类除了对基本类型进行一个拷贝之外,还分别对引用类型进行拷贝,从而实现了深拷贝,因此p2的值更改时不会影响p1的值,在这里要特别注意的是数组也是属于引用类型的一种。