java 中浅克隆与深克隆

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章