Java編程基礎-----對象的深度拷貝

在實際的編程過程中,我們常常會發現這樣一個問題:

兩個對象中的內容是一模一樣的,但是修改其中一個對象時,另外一個對象中的值也會相應的改變,這是因爲在java的對象Clone方法中,賦值的是對象的引用地址,而不是對象中的具體的數據值,要的到一模一樣的數據且相互之間不產生影響,這就涉及到對象的深層拷貝,

對象的深層拷貝有以下兩種方法可以實現:

1、對Clone的對象實現Cloneable的接口,同時重寫Clone方法

package DeepCopy;

public class Person implements Cloneable{
	private String name;
	private Double salary;
	private  int workAge;
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Person person=new Person();
		person.name=name;
		person.salary=salary;
		person.workAge=workAge;
		return person;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	public int getWorkAge() {
		return workAge;
	}
	public void setWorkAge(int workAge) {
		this.workAge = workAge;
	}

}
調用方式如下:

package DeepCopy;

import java.util.ArrayList;
import java.util.List;

public class DeepTestDemo {

	public static List<Person> CloneMethod(List<Person> sources)
			throws CloneNotSupportedException {
		ArrayList<Person> targetpersonList = new ArrayList<Person>();
		for (Person Per : sources) {
			targetpersonList.add((Person) Per.clone());
		}
		return targetpersonList;
	}

	public static void main(String[] args) throws CloneNotSupportedException {
		ArrayList<Person> sourcepersonList = new ArrayList<Person>();

		for (int i = 0; i <= 10; i++) {
			Person per = new Person();
			per.setName("Person#" + i);
			per.setSalary(Double.valueOf(i));
			per.setWorkAge(i + 10);
			sourcepersonList.add(per);
		}

		System.out.println("原始數據List存儲地址:" + sourcepersonList.toString());
		System.out.println("Clone之後新數據List的存儲地址:"
				+ CloneMethod(sourcepersonList).toString());
	}

}
測試結果如下:

原始數據List存儲地址:[DeepCopy.Person@1fb8ee3, DeepCopy.Person@61de33, DeepCopy.Person@14318bb, DeepCopy.Person@ca0b6, DeepCopy.Person@10b30a7, DeepCopy.Person@1a758cb, DeepCopy.Person@1b67f74, DeepCopy.Person@69b332, DeepCopy.Person@173a10f, DeepCopy.Person@530daa, DeepCopy.Person@a62fc3]
Clone之後新數據List的存儲地址:[DeepCopy.Person@89ae9e, DeepCopy.Person@1270b73, DeepCopy.Person@60aeb0, DeepCopy.Person@16caf43, DeepCopy.Person@66848c, DeepCopy.Person@8813f2, DeepCopy.Person@1d58aae, DeepCopy.Person@83cc67, DeepCopy.Person@e09713, DeepCopy.Person@de6f34, DeepCopy.Person@156ee8e]

2、對Clone的對象實現Serializable的接口

package DeepCopy;

import java.io.Serializable;

public class Student implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	

}
使用方法

package DeepCopy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class DeepTestDemo2 {

	public static List deepCopy(List src) throws IOException,
			ClassNotFoundException {
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
		ObjectOutputStream out = new ObjectOutputStream(byteOut);
		out.writeObject(src);

		ByteArrayInputStream byteIn = new ByteArrayInputStream(
				byteOut.toByteArray());
		ObjectInputStream in = new ObjectInputStream(byteIn);
		List dest = (List) in.readObject();
		return dest;
	}

	public static void main(String[] args) throws IOException,
			ClassNotFoundException {
		ArrayList<Student> sourcestuList = new ArrayList<Student>();
		for (int i = 0; i <= 10; i++) {
			Student stu = new Student();
			stu.setName("stu#" + i);
			stu.setAge(i);
			sourcestuList.add(stu);
		}

		System.out.println("原始數據List存儲地址:" + sourcestuList.toString());
		System.out.println("DeepCopy之後新數據List的存儲地址:"
				+ deepCopy(sourcestuList).toString());
	}
}
測試結果

原始數據List存儲地址:[DeepCopy.Student@1fb8ee3, DeepCopy.Student@61de33, DeepCopy.Student@14318bb, DeepCopy.Student@ca0b6, DeepCopy.Student@10b30a7, DeepCopy.Student@1a758cb, DeepCopy.Student@1b67f74, DeepCopy.Student@69b332, DeepCopy.Student@173a10f, DeepCopy.Student@530daa, DeepCopy.Student@a62fc3]
DeepCopy之後新數據List的存儲地址:[DeepCopy.Student@32c41a, DeepCopy.Student@e89b94, DeepCopy.Student@13e205f, DeepCopy.Student@1bf73fa, DeepCopy.Student@5740bb, DeepCopy.Student@5ac072, DeepCopy.Student@109a4c, DeepCopy.Student@201f9, DeepCopy.Student@1cf8583, DeepCopy.Student@14693c7, DeepCopy.Student@901887]

總結:本人比較推薦第二種方式,因爲第一種方式,若在Person類中加上其他的類的對象作爲成員變量Obj,那麼加進來的對象Obj的類也需要繼承Cloneable接口,同時重寫Clone方式,同時還要在Person類中Clone方法中添加Obj.clone()來實現對象的克隆。

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