Blog信息 |
blog名称:小鸟吹烟 日志总数:157 评论数量:424 留言数量:-1 访问次数:1249293 建立时间:2006年10月23日 |

| |
[J2SE]java clone() 文章收藏, 网上资源, 软件技术
tone 发表于 2007/2/26 13:48:52 |
(http://blog.sina.com.cn/u/5377b40a010007ry)
java clone
有时我们确实需要clone一个对象,最好的方法还是使用Object的clone方法,由jdk调用native方法来实现,这样效率比较高。先来个shallow clone,再来deep clone。
shallow clone
代码如下:
待clone的对象
package practisejava.others.clone;
/** * 待clone的对象,必须实现Cloneable这个tag interface */public class ObjectToClone implements Cloneable{ private int i=0; public void setNum(int i){ this.i=i; } public int getNum(){ return this.i; } public void tellNum(){ System.out.println("the number is "+i); } // 重写Object的clone public Object clone() throws CloneNotSupportedException { return (ObjectToClone)super.clone(); }}
clone测试
package practisejava.others.clone;
/** * 测试clone是否成功 */public class CloneTest { public static void main(String[] args) { ObjectToClone otc = new ObjectToClone(); otc.setNum(888); // 开始clone了! ObjectToClone cloneObject = null; try { cloneObject = (ObjectToClone) otc.clone(); } catch (CloneNotSupportedException ex) { System.out.println("Sorry,Clone Not Supported!"); } // 测试clone是否成功 if(cloneObject!=null){ System.out.println("before clone"); System.out.println("ObjectToClone get number : " + otc.getNum()+"\n"); System.out.println("after clone"); System.out.println("ObjectToClone get number : " + otc.getNum()); cloneObject.setNum(999); System.out.println("CloneObject get number : " + cloneObject.getNum()); } }}
执行结果
before cloneObjectToClone get number : 888
after cloneObjectToClone get number : 888CloneObject get number : 999
从运行结果看,修改了clone体的值并没有影响到原来被clone体的值,哈哈,clone成功。高兴得太早了,ObjectToClone里只有简单的非引用属性,如果有引用的属性,还能成吗?答案是否定的!看下面的例子:
被clone对象引用的对象
package practisejava.others.shallowclone;
public class ReferencedObject { private int i = 0; public ReferencedObject(int i) { this.i = i; } public void doubleValue(){ this.i = 2*this.i; } public int getNumber(){ return this.i; }}
待clone对象
package practisejava.others.shallowclone;
/** * 必须实现Cloneable接口,否则调用函数的clone方法时会报CloneNotSupportedException错 */public class ObjectForShallowClone implements Cloneable{ private int i = 0; private ReferencedObject rf = null; public void setNum(int i) { this.i = i; } public void setReferencedObject(ReferencedObject rf){ this.rf = rf; } public int getNumber(){ return this.i; } public ReferencedObject getReferencedObject(){ return this.rf; } // 重写Object的clone public Object clone() throws CloneNotSupportedException { return (ObjectForShallowClone)super.clone(); }}
clone测试
package practisejava.others.shallowclone;
/** * clone测试 */public class CloneTest { public static void main(String[] args) { ObjectForShallowClone ofsc = new ObjectForShallowClone(); ofsc.setNum(888); ofsc.setReferencedObject(new ReferencedObject(1));
// 开始clone了! ObjectForShallowClone deepCloneObject = null; try { deepCloneObject = (ObjectForShallowClone) ofsc.clone(); } catch (CloneNotSupportedException ex) { System.out.println("Sorry,Clone Not Supported!"); }
// 测试clone是否成功 if(deepCloneObject!=null){ System.out.println("before clone"); System.out.println("ObjectForShallowClone get number : " + ofsc.getNumber()); System.out.println("ObjectForShallowClone ReferencedObject get number : "+ofsc.getReferencedObject().getNumber()+"\n"); deepCloneObject.setNum(999); deepCloneObject.getReferencedObject().doubleValue();
System.out.println("after clone"); System.out.println("ObjectForShallowClone get number : " + ofsc.getNumber()); System.out.println("ObjectForShallowClone ReferencedObject get number : " + ofsc.getReferencedObject().getNumber());
System.out.println("CloneObject get number : " + deepCloneObject.getNumber()); System.out.println("CloneObject ReferencedObject get number : " + deepCloneObject.getReferencedObject().getNumber()); } }}
运行结果如下:
before cloneObjectForShallowClone get number : 888ObjectForShallowClone ReferencedObject get number : 1
after cloneObjectForShallowClone get number : 888ObjectForShallowClone ReferencedObject get number : 2CloneObject get number : 999CloneObject ReferencedObject get number : 2
显然,修改了clone对象的引用对象的值后,被clone对象引用对象的值也随之改变。这不是我们想要的效果,改进的方法就是deep clone。
deep clone
被clone对象引用的对象(比shallow clone多加了clone的方法)
package practisejava.others.deepclone;
public class ReferencedObject implements Cloneable{ private int i = 0; public ReferencedObject(int i) { this.i = i; } public void doubleValue(){ this.i = 2*this.i; }
public int getNumber(){ return this.i; }
// 重写clone的方法 public Object clone() throws CloneNotSupportedException { return (ReferencedObject)super.clone(); }}
待clone对象(在clone方法里同时clone引用对象)
package practisejava.others.deepclone;
import practisejava.others.deepclone.ReferencedObject;
public class ObjectForDeepClone implements Cloneable{ private int i = 0; private ReferencedObject rf = null;
public void setNum(int i) { this.i = i; }
public void setReferencedObject(ReferencedObject rf){ this.rf = rf; }
public int getNumber(){ return this.i; }
public ReferencedObject getReferencedObject(){ return this.rf; }
// 重写Object的clone public Object clone() throws CloneNotSupportedException { ObjectForDeepClone cloneObject = (ObjectForDeepClone)super.clone(); // 调用引用对象的clone方法 if(rf!=null){ ReferencedObject rfClone = (ReferencedObject)rf.clone(); cloneObject.setReferencedObject(rfClone); } return cloneObject; }}
clone测试
package practisejava.others.deepclone;
public class CloneTest { public static void main(String[] args) { ObjectForDeepClone ofdc = new ObjectForDeepClone(); ofdc.setNum(888); ofdc.setReferencedObject(new ReferencedObject(1));
// 开始clone了! ObjectForDeepClone deepCloneObject = null; try { deepCloneObject = (ObjectForDeepClone) ofdc.clone(); } catch (CloneNotSupportedException ex) { System.out.println("Sorry,Clone Not Supported!"); }
// 测试clone是否成功 if(deepCloneObject!=null){ System.out.println("before clone"); System.out.println("ObjectForDeepClone get number : " + ofdc.getNumber()); System.out.println("ObjectForDeepClone ReferencedObject get number : "+ofdc.getReferencedObject().getNumber()+"\n");
deepCloneObject.setNum(999); deepCloneObject.getReferencedObject().doubleValue();
System.out.println("after clone"); System.out.println("ObjectForDeepClone get number : " + ofdc.getNumber()); System.out.println("ObjectForDeepClone ReferencedObject get number : " + ofdc.getReferencedObject().getNumber());
System.out.println("CloneObject get number : " + deepCloneObject.getNumber()); System.out.println("CloneObject ReferencedObject get number : " + deepCloneObject.getReferencedObject().getNumber()); } }}
运行结果:
before cloneObjectForDeepClone get number : 888ObjectForDeepClone ReferencedObject get number : 1
after cloneObjectForDeepClone get number : 888ObjectForDeepClone ReferencedObject get number : 1CloneObject get number : 999CloneObject ReferencedObject get number : 2
哇,成功! |
|
Palm's GSM Centro spotted in white 文章收藏, 网上资源, 软件技术
mbt changa shoes birch women(游客)发表评论于2010/4/1 20:33:07 |
Yeah, there it is, a shiny white Palm Centro in a booth for all to see, I'm sure discount mbt shoes sale online Palm will be ever so delighted about this. Apparently cheap mbt shoes sale an accessory vendor put it out to display some of its wares on the show floor and the gents at TreoCentral were there to catch it live. Adding insult to this slip up is that fact that the handset is a GSM model that mbt changa shoes birch women you see there my friends, and interestingly it is different then the AT&T branded Centro we saw a while back. More on this as soon as we can get our grubby mitts on it. |
|
回复:java clone() 文章收藏, 网上资源, 软件技术
tone发表评论于2007/2/26 13:52:25 |
Clone通常有两种类型即浅clone和深clone。首先,分析一下两种的不同。浅clone和深clone都是clone,它们本质区别是对象内部的成员属性(非原生类型属性,如int等)在clone时是否处理为引用。如果仍然保留为引用,则称为浅clone,反之称为深clone。其实这两个概念也是相对的概念。在处理上它们有点区别,浅clone方式得到clone对象即可,深clone方式在得到clone对象后,还需要对引用的成员属性进行“clone”处理。从这个层次上说,深clone并没有什么特别地困难,简单讲就是创建好对象,再设置一些成员属性。 |
|
回复:java clone() 文章收藏, 网上资源, 软件技术
tone发表评论于2007/2/26 13:51:22 |
if(rf!=null){ ReferencedObject
rfClone = (ReferencedObject)rf.clone();cloneObject.setReferencedObject(rfClone);}
// 调用引用对象的clone方法
修改了clone对象的引用对象的值后,被clone对象引用对象的值不会随之改变 |
|
» 1 »
|