Java对象克隆-浅拷贝与深拷贝

目录

1、对象的克隆

1.1 对象的浅拷贝

1.2 对象深拷贝


1、对象的克隆

1.1 对象的浅拷贝

在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。

要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。

public class Person implements Cloneable {

   private String name;

   private int age;

   public Person() {

   }

   public Person(String name, int age) {

      this.name = name;

      this.age = age;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

   public int getAge() {

      return age;

   }

   public void setAge(int age) {

      this.age = age;

   }

   protected Object clone() {

      Object obj = null;

      try {

         obj = super.clone();

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      return obj;

   }

   public String toString() {

      return "Person [name=" + name + ", age=" + age + "]";

   }

}

注意: 该Person 类实现了Cloneable 重写了clone() 方法.

public static void main(String[] args) {

      Person p1 = new Person("jack", 28);

      System.out.println(p1);

      Person p2 = (Person) p1.clone();

      System.out.println(p2);

      // 不是同一个Person 对象.

      System.out.println(p1 == p2);

      // 修改p1 对象属性值,不影响 p2 对象的属性值.

      p1.setAge(30);

      System.out.println(p1);

      System.out.println(p2);

   }

Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。

1.2 对象深拷贝

注意问题:

请看代码:

package cn.test.gz.myclone;

public class Person implements Cloneable {

   private String name;

   private int age;

   private Address add;

   public Person() {

   }

   public Person(String name, int age, Address add) {

      this.name = name;

      this.age = age;

      this.add = add;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

   public int getAge() {

      return age;

   }

   public void setAge(int age) {

      this.age = age;

   }

   public Address getAdd() {

      return add;

   }

   public void setAdd(Address add) {

      this.add = add;

   }

   protected Object clone() {

      Object obj = null;

      try {

         obj = super.clone();

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      return obj;

   }

   @Override

   public String toString() {

      return "Person [name=" + name + ", age=" + age + ", add:" + add + "]";

   }

}

package cn.test.gz.myclone;

public class Address {

   private String country;

   private String city;

   public Address() {

   }

   public Address(String country, String city) {

      this.country = country;

      this.city = city;

   }

   public String getCountry() {

      return country;

   }

   public void setCountry(String country) {

      this.country = country;

   }

   public String getCity() {

      return city;

   }

   public void setCity(String city) {

      this.city = city;

   }

   public String toString() {

      return "country=" + country + ", city=" + city;

   }

}

注意:

Address add = new Address("中国", "广州");

      Person p1 = new Person("jack", 28, add);

      add.setCountry("美国");

      System.out.println(p1);

      Person p2 = (Person) p1.clone();

      System.out.println(p2);

      // 克隆的是两个不同的对象

      System.out.println(p1 == p2);

      // 但是对象内部的成员是同一个对象.

      System.out.println(p1.getAdd() == p2.getAdd());

解决办法:

package cn.test.gz.myclone;

public class Address implements Cloneable {

   private String country;

   private String city;

   public Address() {

   }

   public Address(String country, String city) {

      this.country = country;

      this.city = city;

   }

   public String getCountry() {

      return country;

   }

   public void setCountry(String country) {

      this.country = country;

   }

   public String getCity() {

      return city;

   }

   public void setCity(String city) {

      this.city = city;

   }

   public String toString() {

      return "country=" + country + ", city=" + city;

   }

   @Override

   public Object clone() {

      Object obj = null;

      try {

         obj = super.clone();

      } catch (CloneNotSupportedException e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

      }

      return obj;

   }

}

Person 类

protected Object clone() {

      Person p = null;

      try {

         p = (Person) super.clone();

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      p.add = (Address) add.clone();

      return p;

   }

当然也可以通过序列化机制来实现对象的克隆.

public static void main(String[] args) throws IOException, ClassNotFoundException {

      Address add = new Address("中国", "广州");

      Person p1 = new Person("jack", 28, add);

      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

            "c:\\person.txt"));

      oos.writeObject(p1);

      ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:\\person.txt"));

      Person p2=(Person)ois.readObject();

      System.out.println(p1==p2);

      System.out.println(p1.getAdd()==p2.getAdd());

   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

棉花糖老丫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值