前言:
我们经常会遇到某个已有对象A,创建出另外一个与A具有相同状态的对象B,并且对B的修改不会影响A的状态,这就需要clone一个对象实例。在Java语言中简单的复制操作无法达到这个目的(对象的赋值属于引用传递,传递的是地址),而Java提供clone方法解决这个问题。
步骤:
1.继承Cloneable接口(Cloneable是标识接口,没有任何方法)
2.在类中重写Object类中的clone方法
3.在clone方法中调用super.clone()方法
4.把浅复制的引用对象指向原型对象的新克隆体
克隆类:
public class cloneClass implements Cloneable{ //1.继承Cloneable接口
private int anInt=0;
public int getAnInt() {
return anInt;
}
public void setAnInt(int anInt) {
this.anInt = anInt;
}
public void changeInt(){
this.anInt=1;
}
public Object clone(){ //2.在类中重写Object类中的clone方法
cloneClass o = null;
try {
o=(cloneClass)super.clone();//3.在clone方法中调用super.clone()方法
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
测试类:
class test{
public static void main(String[] args) {
cloneClass a = new cloneClass();
cloneClass b = (cloneClass) a.clone(); //4.把浅复制的引用对象指向原型对象的新克隆体
//原始 a b的值
System.out.println("a:"+a.getAnInt());
System.out.println("b:"+b.getAnInt());
b.changeInt();
//克隆之后
System.out.println("a:"+a.getAnInt());
System.out.println("b:"+b.getAnInt());
}
}
程序运行结果
a:0
b:0
a:0
b:1
对象b调用函数changeInt函数,改变了b的anInt的值,而对象a的anInt值并未改变。这就是clone的功能。
深复制与浅复制
在类中只有一些基本的数据类型的时候,采用上述的方法就可以了,但是类中包含对象时就要用到深复制。实现的方法是在对对象调用clone()方法完成复制之后,接着对对象中的非基本类型的属性也调用clone()方法完成深复制。
import java.util.Date;
class deepclone implements Cloneable{
private Date birth = new Date();
public Date getBirth(){
return birth;
}
public void setBirth(){
this.birth=birth;
}
public void changeDate(){
this.birth.setMonth(0);
}
public Object clone(){
deepclone d=null;
try {
d = (deepclone)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
d.birth=(Date)this.getBirth().clone(); //对对象中的非基本类型的属性也调用clone()方法完成深复制
return d;
}
}
class TestRef{
public static void main(String[] args) {
deepclone a = new deepclone();
deepclone b = new deepclone();
System.out.println("b改变之前");
System.out.println("a="+a.getBirth());
System.out.println("b="+b.getBirth());
b.changeDate();
System.out.println("b改变之后");
System.out.println("a="+a.getBirth());
System.out.println("b="+b.getBirth());
}
}
----------------------------------------------------------------------------------------------------------------------------------参考《Java程序员面试笔试宝典》