书上一道例题,解惑。

zhouYunan2010 2011-05-15 11:59:07
是关于深拷贝还是浅拷贝的问题:


import java.util.*;

public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
Employee orginal = new Employee("Tom",5255);
orginal.setHiredate(2000, 1, 1);
Employee copy = (Employee)orginal.clone();
copy.raiseSalary(10);
copy.setHiredate(2011, 3, 4);
System.out.println("orginal="+orginal);
System.out.println("copy="+copy);
}
}
class Employee implements Cloneable{

private String name;
private double salary;
private Date hiredate;

public Employee(String n,double s){
this.name = n;
this.salary = s;
}
public String toString() {
String str = "Employee[name="+name+",salary="+salary+",hiredate="+hiredate+"]";
return str;
}

public Object clone() throws CloneNotSupportedException {
//Employee cloned = (Employee)super.clone();
//cloned.hiredate = (Date)hiredate.clone();
//return cloned;
return super.clone(); //默认是浅拷贝
}

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

public void setHiredate(int year,int month,int day) {
hiredate = new GregorianCalendar(year,month-1,day).getTime();
}


}



对于基本类型,浅拷贝足已。
但对于成员变量hiredate 为Date类型,拷贝不了。所以原对象和拷贝的对象还是指向同一个Date
但为什么打印出的orginal 和 copy 中的日期数据不一样,他们的Date难道不是同一个引用吗?
...全文
173 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
qybao 2011-05-17
  • 打赏
  • 举报
回复
LS说的很清楚了
浅拷贝是成员数据之间直接赋值,深拷贝是成员数据重新申请内存空间,并进行数据内容复制
简单举例
class A {
String name;
}
浅拷贝
A a = new A();
A b = a.浅拷贝();实际的处理类似于
A b = new A();
b.name = a.name //这个叫做浅拷贝,成员对象直接赋值

深拷贝
A a = new A();
A b = a.浅拷贝();实际的处理类似于
A b = new A();
b.name = new String(a.name) //这个叫做浅拷贝,成员对象重新new,并进行内容复制

这样,浅拷贝时,成员数据引用的是同一个对象,即a.name和b.name指向同一个内存地址
而深拷贝,成员数据分别引用的不同的对象,即a.name和b.name指向不同的内存地址

注意,浅拷贝虽然成员指向相同的对象地址,但成员本身是独立互不干涉的,也就说二者不是一体,只是大家的值相同(值都是同一个对象的地址),所以b.name=xxx可以改变b的name指向新的对象,但并不影响a.name。
同理,LZ的代码中,copy调用了setHiredate,里面改变了copy的hiredate,使它指向新的内存,而orginal的hiredate并没有发生改变





chosen0ne 2011-05-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zhouyunan2010 的回复:]

浅拷贝的话orginal.hiredate与copy.hiredate应该是同一个引用啊。
copy.hiredate被赋予了新的对象地址,为什么orginal.hiredate还是老的地址?
[/Quote]

浅拷贝的话orginal.hiredate与copy.hiredate应该是同一个引用啊。这句话不对,他们是两个引用,只不过是这两个引用指向同一个对象(就是说引用的值是相等的),举个简单的例子,和这种情况是一样的:

String a=new String("i'm a");
String b=a;
String b=new String("i'm b");

上面的代码中,a为i'm a而b是i'm b;
浅拷贝类似与这个例子,只是简单的引用赋值(b=a)

zhouYunan2010 2011-05-17
  • 打赏
  • 举报
回复
浅拷贝的话orginal.hiredate与copy.hiredate应该是同一个引用啊。
copy.hiredate被赋予了新的对象地址,为什么orginal.hiredate还是老的地址?
chosen0ne 2011-05-17
  • 打赏
  • 举报
回复
1L正解

在setHiredate方法中,new了一个新对象
在没有执行copy.setHiredate(2011, 3, 4);这段代码之前,copy.hiredate==orginal.hiredate返回的是true,它们指向同一对象。但是执行过copy.setHiredate(2011, 3, 4);之后,copy.hiredate被赋值为新new出的对象的地址,所以copy.hiredate和orginal.hiredate指向的不是同一个对象。

楼主可以试试修改setHiredate方法,让它不是new一个对象,而是调用hiredate.setXXX()方法修改hiredate的状态,这样就可以发现浅拷贝了。。。

还可以看一下这篇文章
http://blog.csdn.net/chosen0ne/archive/2011/03/30/6290186.aspx
zhouYunan2010 2011-05-15
  • 打赏
  • 举报
回复
虽然new了。但是如果成员变量hiredate没有被拷贝。赋给的是同一个hiredate
打印应该是:
orginal=Employee[name=Tom,salary=5255.0,hiredate=Fri Mar 04 00:00:00 CST 2011]
copy=Employee[name=Tom,salary=5780.5,hiredate=Fri Mar 04 00:00:00 CST 2011]
一样的Date型数据

而现在打印的是:
orginal=Employee[name=Tom,salary=5255.0,hiredate=Sat Jan 01 00:00:00 CST 2000]
copy=Employee[name=Tom,salary=5780.5,hiredate=Fri Mar 04 00:00:00 CST 2011]
不一样的Date型数据
说明浅拷贝也拷贝了Date类型的hiredate
茫茫大海 2011-05-15
  • 打赏
  • 举报
回复
你在setHiredate方法中new了,所以他们已经指向了不同的对象。

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧