Java clone() 浅克隆与深度克隆

内容转自:http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.htmlhtml

如今Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过一阵子,在java中也有这么一个概念,它可让咱们很方便的“制造”出一个对象的副原本,下面来具体看看java中的Clone机制是如何工做的?
     1. Clone&Copy
     假设如今有一个Employee对象,Employee tobby =new Employee(“CMTobby”,5000),通
常咱们会有这样的赋值Employee cindyelf=tobby,这个时候只是简单了copy了一下reference,cindyelf和tobby都指向内存中同一个object,这样cindyelf或者tobby的一个操做均可能影响到对方。打个比方,若是咱们经过cindyelf.raiseSalary()方法改变了salary域的值,那么tobby经过getSalary()方法获得的就是修改以后的salary域的值,显然这不是咱们愿意看到的。咱们但愿获得tobby的一个精确拷贝,同时二者互不影响,这时候咱们就可使用Clone来知足咱们的需求。Employee cindy=tobby.clone(),这时会生成一个新的Employee对象,而且和tobby具备相同的属性值和方法。java


      2. Shallow Clone&Deep Clone
Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。这样,问题就来了咯,以Employee为例,它里面有一个域hireDay不是基本型别的变量,而是一个reference变量,通过Clone以后就会产生一个新的Date型别的reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:
学习

 

这个时候咱们就须要进行deep Clone了,对那些非基本型别的域进行特殊的处理,例如本例中的hireDay。咱们能够从新定义Clone方法,对hireDay作特殊处理,以下代码所示:spa

 1 class Employee implements Cloneable
 2 
 3 {
 4         public Object clone() throws CloneNotSupportedException
 5         {
 6          Employee cloned = (Employee) super.clone();
 7       cloned.hireDay = (Date) hireDay.clone()
 8       return cloned;
 9         }
10 }

 

3. Clone()方法的保护机制

在Object中Clone()是被申明为protected的,这样作是有必定的道理的,以Employee

类为例,经过申明为protected,就能够保证只有Employee类里面才能“克隆”Employee对象,原理能够参考我前面关于public、protected、private的学习笔记。.net



4. Clone()方法的使用

Clone()方法的使用比较简单,注意以下几点便可:

a. 何时使用shallow Clone,何时使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别仍是reference variable

b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,不然在调用Clone方法的时候会抛出CloneNotSupportedException。code