利用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);
}
}


[b]输出结果:
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]
[/b]

我们可以看到,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();
}
}
}


[b]输出结果:
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][/b]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值