Clone的简单使用

public class Employee implements Cloneable{
private float salary;
private String name;
private Date hireDay;
/**
 * 使用场景:比如在方法中传递一个对象,这时候你需要使用到这个对象进行操作,你需要做更新对象的相关数据,
 * 但是又不想改变这个对象,因为更新对象的操作应用只是在方法里面,这时候可以克隆一份对象进行操作即可
 * 
 * 使用场景:在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,
 * 并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在Java语言中,
 * 用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段
 * 
 * 相关网页说明:
 * 1、http://blog.csdn.net/shootyou/article/details/3945221
 * 2、http://blog.csdn.net/it_man/article/details/1404550
 * 3、http://blog.csdn.net/naivesoft/article/details/6774550   【java克隆中String的特殊性】
 * 
 * 影子克隆和深度克隆的区别:
 * 调用Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,
 * 但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。
 * 
 * 注:克隆的话是八大基本类型加上String类型,因为String类型是不可改变的,每次赋值都会分配新的一块内存
 */
/**
 * 
 * @param args
 * @throws CloneNotSupportedException 如果不实现Cloneable接口,那么一定会抛出这个异常
 */
public static void main(String[] args) throws CloneNotSupportedException {
	Employee e=new Employee(3000.0f,"xw",new Date());
	/* 浅复制(Shallow Clone)
	 * Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy
	 * 它里面有一个域hireDay不是基本型别的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型别的
	 * reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息
	 */
	Employee e1=(Employee)e.clone();
	System.out.println(e1.hashCode()+":"+e.hashCode());//两个对象不一样了,hashcode不一样
	e1.salary=200;
	e1.name="hj";
	e1.hireDay.setDate(9);
	System.out.println(e.salary+"#"+e1.salary);//3000.0#200.0
	System.out.println(e.name+"#"+e1.name);	   //xw#hj  ??这里应该也是引用的改变,不知道为什么原来的name没改变
	System.out.println(e.hireDay.getDate()+"#"+e1.hireDay.getDate());//9#9  
	//因为是浅复制,所以引用变量会共享信息
	//但是当重写了clone方法之后得到的值是7#9
	
}

public Employee(float salary,String name,Date hireDay){
	this.salary=salary;
	this.name=name;
	this.hireDay=hireDay;
}

@Override
/*
 * 为了不让引用变量与原来被克隆的对象不共享同一份数据,需要进行深复制(deep Clone)
 * 重新定义Clone方法,对那些非基本型别的域进行特殊的处理
 */
protected Object clone() throws CloneNotSupportedException {
	Employee clone=(Employee)super.clone();//对e对象的一份克隆,生成一份全新的对象
	clone.hireDay=(Date)hireDay.clone();//对成员变量的一份克隆,避免与被克隆的对象共用同一份引用
	//这时候得到的hireDay是还未改变过的hireDay,还停留在创建对象为构造方法赋值的时候的变量值
	return clone;
}
}
/**
  输出结果:
  14576877:12677476
  3000.0#200.0
  xw#hj
  24#9
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值