快速业务通道

浅析Java的“克隆”方法 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-23
法(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出CloneNotSupportedException异常。

以上是clone的最基本的步骤,想要完成一个成功的clone,还要了解什么是"影子clone"和"深度clone"。

浅析Java的“克隆”方法(4)

时间:2010-09-28

什么是影子clone?

下面的例子包含三个类UnCloneA,CloneB,CloneMain。CloneB类包含了一个UnCloneA的实例和一个int类型变量,并且重载clone()方法。CloneMain类初始化UnCloneA类的一个实例b1,然后调用clone()方法生成了一个b1的拷贝b2。最后考察一下b1和b2的输出:

package clone; class UnCloneA {  private int i;  public UnCloneA(int ii) { i = ii; }  public void doublevalue() { i *= 2; }  public String toString() {   return Integer.toString(i);  } } class CloneB implements Cloneable{  public int aInt;  public UnCloneA unCA = new UnCloneA(111);  public Object clone(){   CloneB o = null;   try{    o = (CloneB)super.clone();   }catch(CloneNotSupportedException e){    e.printStackTrace();   }   return o;  } } public class CloneMain {  public static void main(String[] a){   CloneB b1 = new CloneB();   b1.aInt = 11;   System.out.println("before clone,b1.aInt = "+ b1.aInt);   System.out.println("before clone,b1.unCA = "+ b1.unCA);   CloneB b2 = (CloneB)b1.clone();   b2.aInt = 22;   b2.unCA.doublevalue();   System.out.println("=================================");   System.out.println("after clone,b1.aInt = "+ b1.aInt);   System.out.println("after clone,b1.unCA = "+ b1.unCA);   System.out.println("=================================");   System.out.println("after clone,b2.aInt = "+ b2.aInt);   System.out.println("after clone,b2.unCA = "+ b2.unCA);  } } /** RUN RESULT: before clone,b1.aInt = 11 before clone,b1.unCA = 111 ================================= after clone,b1.aInt = 11 after clone,b1.unCA = 222 ================================= after clone,b2.aInt = 22 after clone,b2.unCA = 222 */

输出的结果说明int类型的变量aInt和UnCloneA的实例对象unCA的clone结果不一致,int类型是真正的被clone了,因为改变了b2中的aInt变量,对b1的aInt没有产生影响,也就是说,b2.aInt与b1.aInt已经占据了不同的内存空间,b2.aInt是b1.aInt的一个真正拷贝。相反,对b2.unCA的改变同时改变了b1.unCA,很明显,b2.unCA和b1.unCA是仅仅指向同一个对象的不同引用!从中可以看出,调用Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。

大多时候,这种clone的结果往往不是我们所希望的结果,这种clone也被称为"影子clone"。要想让b2.unCA指向与b2.unCA不同的对象,而且b2.unCA中还要包含b1.unCA中的信息作为初始信息,就要实现深度clone。

浅析Java的“克隆”方法(5)

时间:2010-09-28

怎么进行深度clone?

把上面的例子改成深度clone很简单,需要两个改变:一是让UnCloneA类也实现和CloneB类一样的clone功能(实现Clonea

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号