在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未被影响