是关于深拷贝还是浅拷贝的问题:
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难道不是同一个引用吗?
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难道不是同一个引用吗?
解决方案 »
- 如何将数据库查询结果 写入xml ?
- 谢谢啦 真的想不出....
- 帮助分析一下这个考试题目
- 错误the type EWindow must implement the inherited abstract method itemlistener怎么解决?
- 越学越不懂了
- 怎样在被调用方法里,得到调用它的对象的实际类型?
- JComboBox能否跟html中的select控件一样,值和显示的文本可以分开来设置
- 如何将window设置为window服务,网上教程很多但都不能下载相关软件
- 请问怎样设置web应用程序部署文件启动server端socket监听程序,并且web服务能够正常启动
- 如何进行IP验证???
- java压缩文件出现乱码问题
- 代码质量的疑问...
打印应该是:
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
在没有执行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
copy.hiredate被赋予了新的对象地址,为什么orginal.hiredate还是老的地址?
浅拷贝的话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)
浅拷贝是成员数据之间直接赋值,深拷贝是成员数据重新申请内存空间,并进行数据内容复制
简单举例
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并没有发生改变