是关于深拷贝还是浅拷贝的问题:
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难道不是同一个引用吗?

解决方案 »

  1.   

    你在setHiredate方法中new了,所以他们已经指向了不同的对象。
      

  2.   

    虽然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
      

  3.   

    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
      

  4.   

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

  5.   


    浅拷贝的话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)
      

  6.   

    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并没有发生改变