java中的克隆

在java中标识哪个类是可以克隆的,需要该类实现Cloneable接口,它是在java.lang包中自动导入的,是个空接口,只作为一个标识.假如一个Student类,属性成员都是基本类型或者不可变对象的引用(像String类型)的话,java浅表复制也不会出现问题,但是当Student类中含有一个属性是引用类型时,如Address类,则这种情况下浅表克隆的student对象与原来的student对象就拥有对Address成员属性相同的引用,当克隆的对象修改时,也会改变原来student对象的内容.如果想使得克隆出来的对象彻底获得独立性,就需要进行深度克隆.下面的代码是我学习clone方法时候自己写的"深度克隆",拿上来献丑了.

Student.java

package hyp;

public class Student implements Cloneable {  private String id;  private String name;  private Address address;  public Student(){   this("","");   address = null;  }  public Student(String id,String name){   this.id = id;   this.name = name;   this.address = new Address();  }  public String getId() {   return id;  }  public void setId(String id) {   this.id = id;  }  public String getName() {   return name;  }  public void setName(String name) {   this.name = name;  }  public Student clone(){   Student stu = null;   try {    stu = (Student)super.clone();    Address address = this.getAddress();    Address newAddress = address.clone();    stu.setAddress(newAddress);       } catch (CloneNotSupportedException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }   return stu;  }   public Address getAddress() {   return address;  }  public void setAddress(Address address) {   this.address = address;  }   }

Address.java

package hyp;

public class Address implements Cloneable{  private String province;  private String city;  private String strict;    public String getCity() {   return city;  }  public void setCity(String city) {   this.city = city;  }  public String getProvince() {   return province;  }  public void setProvince(String province) {   this.province = province;  }  public String getStrict() {   return strict;  }  public void setStrict(String strict) {   this.strict = strict;  }    public Address clone(){   Address address = null;   try {    address = (Address)super.clone();   } catch (CloneNotSupportedException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }   return address;  }   }

 

Main.java

package hyp;

public class Main {

 /**   * @param args   */

 public static void main(String[] args) {   // TODO Auto-generated method stub   Student stu1 = new Student("0004","David");   Address address = stu1.getAddress();   address.setProvince("Shandong");   address.setCity("Taian");   address.setStrict("Xintai");   System.out.println(stu1.getId()+"  "+stu1.getName()+"  "+address.getProvince()     +"  "+address.getCity()+"  "+address.getStrict());   Student stu2 = null;   stu2 = stu1.clone();   Address address2 = stu2.getAddress();   System.out.println(stu2.getId()+"  "+stu2.getName()+"  "+address2.getProvince()     +"  "+address2.getCity()+"  "+address2.getStrict());   System.out.println("stu1="+stu1);   System.out.println("stu2="+stu2);   System.out.println("address="+address);   System.out.println("address2="+address2);  }

} 这样克隆的student对象在更改某一属性的时候就跟原来的母体没关系了,因为彼此的对象内容分配了不同的内存空间.另外查看JDK帮助文档,可以看到object类的clone方法是受保护的,是native的,我们知道,native方法的效率一般来说都是远高于java中的非native方法。这也说明了new一个对象,然后将原对象中的数据导入到新创建的对象中去的做法是多么愚蠢.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值