在java的Object 類中有Clone方法,用來對對象進行克隆,但要用clone方法,必須將類先實現Cloneable接口
java中的克隆分爲淺克隆和深克隆
代碼爲例
public class Dog implements Cloneable {
public String name;
public Head head;
public int id;
public Dog() {
}
public void changeHeadId(int id){
this.head.setId(id);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Dog(String name, int id,Head head) {
this.name = name;
this.id = id;
this.head = head;
}
}
Dog類實現Cloneable接口,重寫了Object 中的clone方法,調用super.clone()返回克隆後的對象
public class Head {
private int id ;
public Head(int id){
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Dog中的Head類,用來區別淺克隆和深克隆
import org.junit.Test;
public class TestClone {
@Test
public void testClone() {
// 聲明dog1和dog2 將dog1克隆
Dog dog1 = new Dog("doly", 1,new Head(1));
Dog dog2 = null;
try {
dog2 = (Dog) dog1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//改變dog1的屬性值
dog1.name = "nelly";
dog1.id = 2;
dog1.changeHeadId(2);
//輸出dog1
System.out.println("dog1: name =" + dog1.name +",id ="+dog1.id +",head ="+dog1.head.getId());
//輸出dog2
System.out.println("dog2: name =" + dog2.name+",id ="+dog2.id+",head ="+dog2.head.getId());
}
}
輸出結果:
dog1: name =nelly,id =2,head =2
dog2: name =doly,id =1,head =2
在dog1克隆之後,dog1屬性域中的值都做了改變,String類型的name屬性和int類型的id屬性改變後都沒有影響到dog2,但是Head中的id卻被影響,
這是因爲在克隆時,複製的是被克隆對象中屬性域的引用值,就是說將dog1的Head屬性的引用賦值給了dog2的Head屬性,兩個引用指向同一塊內存的同一個head對象,
dog1改變該head對象id的值,dog2當然會受到影響。
這是淺克隆,淺克隆只能複製對象中的String.int .char.等基本類型屬性,不能對數組和對象進行復制
解決方法:使用深克隆
public class Head implements Cloneable{
private int id ;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Head(int id){
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
將Head類實現Cloneable重寫clone()方法
在Dog中改變Clone方法,將克隆後的dog對象的head再次克隆
@Override
protected Object clone() throws CloneNotSupportedException {
Dog dog = (Dog) super.clone();
dog.head = (Head)this.head.clone();
return dog;
}
輸出結果:
dog1: name =nelly,id =2,head =2
dog2: name =doly,id =1,head =1
dog2中的head未被影響