最近在帮忙写单侧的时候,经常会和这几个对象类打交道,因为对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]