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未被影響


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