本站首页    管理页面    写新日志    退出

«July 2025»
12345
6789101112
13141516171819
20212223242526
2728293031


公告

  如果你忍了,欺负你的人将来可能就进监狱了。如果你反击,欺负你的人将来可能就获选十大杰出青年了。

        QQ: 3159671

http://greenboy.javaeye.com/

http://blog.sina.com.cn/u/1278341164 小鸟吹烟


我的分类(专题)

日志更新

最新评论

留言板

链接

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 哇,成功!


阅读全文(4865) | 回复(3) | 编辑 | 精华
 


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 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.063 second(s), page refreshed 144758727 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号