`

利用clone来克隆对象

 
阅读更多
谈到对象克隆,有人说:我直接把一个对象赋给另外一个对象不就是克隆了吗?
这样做其实是不对的,因为如果是简单赋值的话,这2个对象会指向同一块内存区域,
这样的话,改变一个对象的变量也将会改变另一个。

我们下面来举个例子,看一下是不是这样。

我们先做一个Employee类,代码如下:
package corejava2.objects;

import java.util.*;

public class Employee {
	private String name;
	private double salary;
	private Date hireDay;

	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
	}

	public void setHireDay(int year, int month, int day) {
		// GregorianCalendar是指阳历时间
		hireDay = new GregorianCalendar(year, month - 1, day).getTime();
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}

	public String toString() {
		return "Employee[name=" + name + ",salary=" + salary + ",hireDay="
				+ hireDay + "]";
	}
}


然后,我们做一个客户端代码用来测试下简单拷贝会是什么样子,代码如下:
package corejava2.basic.clone;

import corejava2.objects.*;

public class CopyTest {
	public static void main(String[] args) {
		Employee original = new Employee("David Anthony", 50000); 
		Employee copy = original;
		
	  original.setHireDay(2008, 1, 1);
	  copy.raiseSalary(10);
	  
	  System.out.println("original: " + original);
	  System.out.println("copy: " + copy);
	}
}


输出结果:
original: Employee[name=David Anthony,salary=55000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]
copy: Employee[name=David Anthony,salary=55000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]


我们可以看到,original对象和copy对象的工资是一样的,这样是不对的,因为我们只是增加了original的工资,那么要怎样解决呢?只有利用克隆。

新的代码如下:

首先,我们需要改造下Employee类,让它能支持克隆,如下:
package corejava2.objects;

import java.util.*;

public class Employee implements Cloneable {
	private String name;
	private double salary;
	private Date hireDay;

	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
	}

	public Employee Clone() throws CloneNotSupportedException {
		// call Object.clone()
		Employee cloned = (Employee) super.clone();

		// clone mutable fields
		cloned.hireDay = (Date) hireDay.clone();

		return cloned;
	}

	public void setHireDay(int year, int month, int day) {
		// GregorianCalendar是指阳历时间
		hireDay = new GregorianCalendar(year, month - 1, day).getTime();
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}

	public String toString() {
		return "Employee[name=" + name + ",salary=" + salary + ",hireDay="
				+ hireDay + "]";
	}
}


接着,我们写下客户端代码:
package corejava2.basic.clone;

import corejava2.objects.Employee;

public class CloneTest {
	public static void main(String[] args) {
		try {
			Employee original = new Employee("David Anthony", 50000);
			original.setHireDay(2008, 1, 1);
			Employee clone = original.Clone();
			
			original.raiseSalary(10);

			System.out.println("original: " + original);
			System.out.println("clone: " + clone);
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}	
	}
}


输出结果:
original: Employee[name=David Anthony,salary=55000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]
clone: Employee[name=David Anthony,salary=50000.0,hireDay=Tue Jan 01 00:00:00 CST 2008]


可以看到这时工资不一样了。

需要注意的是:默认的克隆操作,即从Object继承过来的是浅拷贝,如果我们的类中有其他对象,也就是非基本类型的成员,我们需要重写Clone()方法。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics