Java中的克隆Cloneable

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

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这样不容许改变的类
在其生命周期中不会发生变化,既没有修改它们的方法,也没有建立对它们的引用的方法
安全


                                                                  浅克隆
                                                             spa

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

深克隆
可是,更为常见的状况是子对象是可变的,这就要用到深克隆了。咱们须要从新定义clone()方法。对那些非基本型别的域进行特殊的处理,例如本例中的hireDay。咱们能够从新定义clone()方法,对hireDay作特殊处理,以下代码: orm

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类型。

具体的实现方法是:

一、实现Cloneable接口
二、重写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序列化:很容易实现,并且也很安全。但效率低。 生命周期

相关文章
相关标签/搜索