淺克隆與深克隆
當拷貝一個變量時,原始變量與拷貝變量引用了同一個對象。那麼當改變一個變量所引用的對象時,就會對另外一個變量產生影響。形象化一點說,就像某人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序列化:很容易實現,並且也很安全。但效率低。 生命週期