浅谈java的深浅拷贝

来源:互联网 发布:ubuntu caffe cuda 编辑:程序博客网 时间:2024/05/16 19:05
 
首先,先介绍一下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的值,在这里要特别注意的是数组也是属于引用类型的一种。
原创粉丝点击