我酷下载
您的位置:首页-> 技术文章-> -> Java-> java克隆详述(2)

阅读排行




java克隆详述(2)

作者未知 来源未知 加入时间:2006-7-6 人气:90
何为影子clone?先看一下例子。

//倒霉的羊

publicclassSheepimplementsCloneable{

privateStringname;

publicvoidsetName(Stringarg){

name=arg;

}

publicStringgetName(){

returnname;

}

publicObjectclone()throwsCloneNotSupportedException{

returnsuper.clone();

}

}

//羊圈

publicclassSheepfoldimplementsCloneable{

publicSheepsheep;

publicStringname;

publicSheepfold(){

sheep=newSheep();

}

publicObjectclone()throwsCloneNotSupportedException{

returnsuper.clone();

}

}

//克隆

publicclassMain{

publicstaticvoidmain(String[]args)throwsException{

Sheepfoldfold=newSheepfold();

fold.name="小羊圈";

fold.sheep.setName("小羊");

Sheepfoldfold2=(Sheepfold)fold.clone();

System.out.println("fold2.name="+fold2.name);

System.out.println("fold2.sheep.getName()="+fold2.sheep.getName());

fold2.name="大羊圈";

fold2.sheep.setName("大羊");

System.out.println("=====================================");

System.out.println("fold2.name="+fold2.name);

System.out.println("*fold2.sheep.getName()="+fold2.sheep.getName());

System.out.println("fold.name="+fold.name);

System.out.println("*fold.sheep.getName()="+fold.sheep.getName());

System.out.println("=====================================");

}

}

在这个例子中有三个类,Sheep和Sheepflod都实现了Cloneable接口,并且覆写了Object类的clone方法,说明这两个类是具有克隆能力的。注意一点,在Sheepflod中持有一个Sheep的实例,并在Main类中对其进行克隆,结果如下:

fold2.name=小羊圈

fold2.sheep.getName()=小羊

=====================================

fold2.name=大羊圈

*fold2.sheep.getName()=大羊

fold.name=小羊圈

*fold.sheep.getName()=大羊

=====================================

请注意一下结果中带有"*"号的两条结果语句。fold2.sheep和fold.sheep的name都变为了"大羊",很奇怪是吗?在此之前,我们只对fold2.sheep的name赋过值。为什么fold.sheep的name也变为了"大羊"呢?原因很简单,因为它们是指向同一个对象的不同引用。从中可以看出,调用Object类中clone()方法时,首先在内存中划分一块同原对象相同的空间,然后将原对象的内容原样拷贝至新对象。我们知道,java中有基本数据类型,对于基本数据类型,这样的操作是没有问题的,但对非基本类型变量,它们保存的仅仅是对象的引用,这也是为什么clone后非基本类型变量和原对象中的变量指向同一个对象的原因。可能你已经注意到,程序中用到了String类型,即对象,为什么没有出现引用指向同一地址的情况?这是因为String是一个不可更改的类(immutableclass),每次给它赋值时,都会产生一个新的String对象。如Stringstr="a";str+="b";在这两句代码中,当执行str+="b"时,实际上是重新成生了一个值为"ab"的String对象,即重新分配了一块内存空间。以上clone方法通常被称为"影子clone"。"影子clone"给我们留下了一个问题,即多个引用指向同一个对象。如何解决该问题呢?答案为"深度clone"。把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为如下即可:

publicObjectclone()throwsCloneNotSupportedException{

Sheepfoldfold=(Sheepfold)super.clone();

sheep=(Sheep)fold.sheep.clone();

returnfold;

}

至此,clone就基本完成了。当然,在实际使用过程中需要注意一些问题,比如StringBuffer不可以直接clone(当然,也有解决办法)等等。

完!


相关文章
  • java克隆详述(1)
  • 相关软件

    联系我们 广告服务 友情链接 版权说明 软件发布 下载帮助

    CopyRight
    2005-2016 www.5qcn.net All Rights Reserved 版权所有 【我酷】下载