java clone简单学习

最近在帮忙写单侧的时候,经常会和这几个对象类打交道,因为对java也不是很熟悉,刚好学习一下,都是很浅的学习,并没有深入的去学习哈,因为感觉也用不上。

 

  • protected Object clone() throws CloneNotSupportedException

  作用:创建并且返回一个对象的copy 

  在写单侧的时候,有的时候需要从一个已知对象创建出一个新的对象,一开始不知道,直接是用:

  

Member memberA=new Member(
                "Tom",
                new GregorianCalendar(1998,7,10),
                Sex.MAIL,
                "596156210@qq.com"
                );
        
Member memberc=memberA;

本意是想变c,而不去影响A,但是这样引用的话,很明显,改变了c也就变了,因为memberc和membera指向了一个内存地址:

System.out.println(memberA.hashCode());
System.out.println(memberc.hashCode());
//output
4558657
4558657

后来问了开发才知道这里需要copy一个对象才行,实现copy有两种办法

第一:继承Cloneable的接口

具体做法:

public class Member implements Cloneable { 
    public enum Sex{
        MAIL,FEMAIL
    }
    
    private String name;
    private Calendar birthday;
    private String emailaddress;
    private Sex gender;
    
    public Member(String name,Calendar birthday,Sex gender,String emailaddress)
    {
        
        this.name=name;
        this.birthday=birthday;
        this.emailaddress=emailaddress;
        this.gender=gender;
    }
//继承,然后重写clone方法就可以拉    
    @Override
    protected Object clone() throws CloneNotSupportedException {
            return super.clone();
    }
}

那么我通过clone出来的对象就和membera指向了不同的内存地址拉,具体测试:

public static void main(String[] args) throws CloneNotSupportedException {
        // TODO Auto-generated method stub

        Member memberA=new Member(
                "Tom",
                new GregorianCalendar(1998,7,10),
                Sex.MAIL,
                "596156210@qq.com"
                );
        
        Member memberc=memberA;
        Member cloned=(Member)memberA.clone();
        
        //clone的话,cloned和membera应该指向不同的内存地址,但是memberc和memberA是指向同一个地址
        System.out.println(cloned.hashCode());
        System.out.println(memberA.hashCode());
        System.out.println(memberc.hashCode());
            
        //相同的类,所以应该一样
        System.out.println(memberA.getClass().equals(cloned.getClass()));
                
        //一个是clone,一个是引用,所以memberc 和cloned的name值应该不一样
        memberc.setName("hello");
        System.out.println(memberA.getName());
        System.out.println(cloned.getName());
}
//output

32512553
4558657
4558657
true
hello
Tom

 

这是第一种办法,可以看到第一种办法clone的话,首先要继承外部接口,然后呢还有异常检测,另外还要对clone出来的对象Cast一下。

第二种办法的话,通过构造器来做。

    public Member(Member member) {
          this.name = member.getName();
          this.birthday=member.getBirthday();
          this.emailaddress=member.getEmailaddress();
          this.gender=member.getGender();
          
       }

这样的话,我new出来的对象和clone出来的效果差不多。

        //通过拷贝构造器
        Member membere=new Member(memberA);
        System.out.println(membere.hashCode());
        System.out.println(memberA.hashCode());
//output
12590745
4558657

感觉这样方便很多,不用去继承外部接口,也不用管异常,也不用cast了,写单侧的时候我肯定用第二种,毕竟还是对外部依赖少点好么

 相比而言,python里面copy就简单多啦

if __name__=="__main__":
    import copy
    listA=[1,4,3]
    copyB=copy.copy(listA)
    copyB.sort()
    print copyB
    print listA
#output
[1, 3, 4]
[1, 4, 3]
[Finished in 0.5s]

 

 

 

 

 

posted @ 2013-08-22 14:42  夏木友人  阅读(324)  评论(0编辑  收藏  举报