Java中的克隆Cloneable

杀马特。学长 韩版系。学妹 提交于 2019-12-03 21:49:40

浅克隆与深克隆
当拷贝一个变量时,原始变量与拷贝变量引用了同一个对象。那么当改变一个变量所引用的对象时,就会对另一个变量产生影响。形象化一点说,就像某人A有一把遥控,用来控制电视,他把遥控交给了B,B用遥控来改变电视台,则对
A来说,他看的节目台也发生相应变化。

Employee e1 =new Employee(“John”,5000);
Employee e2=e1;
e2.raiseSalary(500);
那么,如果我们希望得到一个拷贝,它与原拷贝互不影响,则就引入了克隆的概念。
Employee e2=e1.clone();
这会产生一个新的Employee对象e2,它与被克隆对象e1有相同的属性。并且e2与e1互不影响。



浅克隆
clone()方法是object类的proteced方法,由于这个类对于具体类一无所知,所以只能对各个域进行拷贝。

如果原始对象与拷贝对象的共享的子对象是不可变的,将不会产生任何问题。例如,
①对象中的所有数据域是数值或基本类型
像String这样不允许改变的类
在其生命周期中不会发生变化,既没有修改它们的方法,也没有创建对它们的引用的方法


                                                                  浅克隆
                                                            

域中包含对象的引用,则会使得克隆后的对象和以前的对象有着相同引用的域。这种只是单纯进行域的拷贝就称作浅克隆,而默认的方法就是浅克隆。

深克隆
但是,更为常见的情况是子对象是可变的,这就要用到深克隆了。我们需要重新定义clone()方法。对那些非基本型别的域进行特殊的处理,例如本例中的hireDay。我们可以重新定义clone()方法,对hireDay做特殊处理,如下代码:

class Employee implements Cloneable  
{  
      public Employee clone() throws CloneNotSupportedException  
      {  
         Employee cloned = (Employee) super.clone();  
         cloned.hireDay = (Date) hireDay.clone();//克隆可变域 
         return cloned;  
      }  
}

注意:在Java SE 5.0以前的版本中,clone()方法返回Object类型。

具体的实现方法是:

1、实现Cloneable接口
2、重写clone()方法,并将其声明为public
注释:在Object类中,clone()方法被声明为protected,因此不能直接通过对象调用anObject.clone()来直接克隆一个对象,而要依次克隆可变实例域。

另外,每个数组都包含了一个clone()方法,其返回值是public,而不是protected。可以利用这个方法创建包含所有数据元素拷贝的一个新数组。例如:

int[] array={1,2,3,4,5};
int[] cloned=array.clone();

cloned[0]=0;//不会改变array[0]的值

另外一种实现克隆的方法是Java序列化机制两者的优缺点如下。
克隆:显得比较笨拙,尤其在可变域较多时,则要依次进行拷贝,比较麻烦。
java序列化:很容易实现,而且也很安全。但效率低。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!