Java中对象拷贝的两种方式

引用的拷贝

1 //引用拷贝
2     private static void copyReferenceObject(){
3         Person p = new Person(23, "zhang");
4         Person p1 = p;
5         System.out.println(p);
6         System.out.println(p1);
7     }

这里打印的结果: 
Person@3654919e 
Person@3654919e 
可以看到,打印的结果是一样的,也就是说,二者的引用是同一个对象,并没有创建出一个新的对象。因此要区分引用拷贝和对象拷贝的区别,下面要介绍的就是对象拷贝。 

浅拷贝

  • 如果pojo中存在的是基本数据类型 ,String 除外 ,实现Cloneable 覆写Clone 方法 这个就是浅拷贝

- code 

 1 package core.java.deeporshoawcopy;
 2 
 3 /**
 4  * @author DGW-PC
 5  * @date 2018年6月7日
 6  * @see 验证   浅拷贝  一般要求实体类使用包装类型 对于深拷贝 类中存在对其他类的引用,也需要实现cloneable接口
 7  */
 8 
 9 class Person implements Cloneable{
10     private String name;
11     private Integer age;
12     public String getName() {
13         return name;
14     }
15     public void setName(String name) {
16         this.name = name;
17     }
18     public Integer getAge() {
19         return age;
20     }
21     public void setAge(Integer age) {
22         this.age = age;
23     }
24     @Override
25     protected Object clone() throws CloneNotSupportedException  {
26         /*Person p=null;
27         try{
28             p=(Person) super.clone();
29         }catch (CloneNotSupportedException e) {
30         }*/
31         return super.clone();
32     }
33 }
34 
35 public class Base {
36     
37      public static void main(String[] args) throws CloneNotSupportedException {
38         Person person = new Person();
39         person.setName("a");
40         person.setAge(12);
41         Person per1=(Person) person.clone();
42         per1.setName("b");
43         per1.setAge(14);;
44         System.out.println(person.getName()+" "+person.getAge().hashCode(0));
45         System.out.println(per1.getName()+" "+per1.getAge());
46     }
47 
48 }

深拷贝

- 如果你的POJO 存在的不是基本上数据类型,可以是自己定义类型,也可以其他包提供的类型 这里以java 提供的Data 的为例子 可以看下面的代码 自身实现clone 方法 你在涉及到使用拷贝的时候一定要注意别的包提供的类是否出现了问题

 1  /**
 2      * Return a copy of this object.
 3      */
 4     public Object clone() {
 5         Date d = null;
 6         try {
 7             d = (Date)super.clone();
 8             if (cdate != null) {
 9                 d.cdate = (BaseCalendar.Date) cdate.clone();
10             }
11         } catch (CloneNotSupportedException e) {} // Won't happen
12         return d;
13     }

- 下面介绍一下基本深拷贝的代码 很短 : 你一定主要 主类包装了多少其他的引用类型的其他类,那么其他必须都要实现Cloneable 接口 以及clone 方法

 1 package core.java.deeporshoawcopy;
 2 
 3 
 4 /**
 5  * @author DGW-PC
 6  * @date 2018年6月7日
 7  * @see 实现序列化  深拷贝
 8  */
 9 
10 class Dog implements Cloneable{
11     private String name;
12 
13     public String getName() {
14         return name;
15     }
16 
17     public void setName(String name) {
18         this.name = name;
19     }
20     @Override
21     protected Object clone() throws CloneNotSupportedException {
22         return super.clone();
23     }
24 }
25 class User implements Cloneable{
26     private String name;
27     private Dog dog;
28     public String getName() {
29         return name;
30     }
31     public void setName(String name) {
32         this.name = name;
33     }
34     public Dog getDog() {
35         return dog;
36     }
37     public void setDog(Dog dog) {
38         this.dog = dog;
39     }
40     @Override
41     protected Object clone() throws CloneNotSupportedException {
42         User u=(User) super.clone();
43         u.dog=(Dog) dog.clone(); //多个需要在全部把关系搞清楚
44         return u;
45     }
46 }
47 
48 public class ObjCloner {
49         public static void main(String[] args) throws CloneNotSupportedException {
50             Dog dog = new Dog();
51             dog.setName("田园犬");
52             User user = new User();
53             user.setDog(dog);
54             user.setName("王二");
55             User user1=(User) user.clone();
56             user1.setName("张三");
57             Dog dog2 = new Dog();
58             dog2.setName("德国牧羊犬");
59             user1.setDog(dog2);
60             System.out.println(user.getName()+"养了"+ user.getDog().getName());
61             System.out.println(user1.getName()+"养了"+ user1.getDog().getName());
62         }
63 }

结果:

 串行化方式实现深拷贝

 - 以下代码着重注意一下 CloneObj方法 ,就行。

  1 package core.java.deeporshoawcopy;
  2 
  3 import java.io.ByteArrayInputStream;
  4 import java.io.ByteArrayOutputStream;
  5 import java.io.ObjectInputStream;
  6 import java.io.ObjectOutputStream;
  7 import java.io.Serializable;
  8 
  9 /**
 10  * @author DGW-PC
 11  * @date 2018年6月7日
 12  * @since 串行化 实现 深拷贝
 13  */
 14 
 15 class Body implements Serializable{
 16     /**
 17      * 
 18      */
 19     private static final long serialVersionUID = 1L;
 20     private String name;
 21     private Fonter fonter;
 22     private Head head;
 23     public String getName() {
 24         return name;
 25     }
 26     public void setName(String name) {
 27         this.name = name;
 28     }
 29     public Fonter getFonter() {
 30         return fonter;
 31     }
 32     public void setFonter(Fonter fonter) {
 33         this.fonter = fonter;
 34     }
 35     public Head getHead() {
 36         return head;
 37     }
 38     public void setHead(Head head) {
 39         this.head = head;
 40     }
 41     @Override
 42     public String toString() {
 43         return "Body [name=" + name + ", fonter=" + fonter + ", head=" + head + "]";
 44     }
 45     public Body(String name, Fonter fonter, Head head) {
 46         super();
 47         this.name = name;
 48         this.fonter = fonter;
 49         this.head = head;
 50     }
 51     
 52     
 53 }
 54 class Head implements Serializable{
 55     /**
 56      * 
 57      */
 58     private static final long serialVersionUID = 1L;
 59     private Integer size;
 60 }
 61 class Fonter implements Serializable{
 62     /**
 63      * 
 64      */
 65     private static final long serialVersionUID = 1L;
 66     private Integer size;
 67 }
 68 class Face implements Serializable{
 69     /**
 70      * 
 71      */
 72     private static final long serialVersionUID = 1L;
 73     private Integer size;
 74 }
 75 public class ObjClonerSeiz {
 76         
 77         private static <T>T  CloneObj(T obj){
 78             T retobj=null;
 79             try {
 80             //写入流中
 81             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 82             ObjectOutputStream oos = new ObjectOutputStream(baos);
 83             oos.writeObject(obj);
 84             //从流中读取
 85             ObjectInputStream ios = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
 86             retobj=(T) ios.readObject();
 87             }catch (Exception e) {
 88                 e.printStackTrace();
 89             }
 90             return retobj;
 91         }
 92     
 93     
 94     
 95         public static void main(String[] args) {
 96                  Body body = new Body("张三", new Fonter(), new Head());
 97                  Body body2=CloneObj(body);
 98                  System.out.println("body==body2  ====>"+(body==body2));
 99                  System.out.println("body.font==body2.font  ====>"+(body.getFonter()==body2.getFonter()));
100                  System.out.println("body.head==body2.head  ====>"+(body.getHead()==body2.getHead()));
101         }
102 }

猜你喜欢

转载自www.cnblogs.com/dgwblog/p/9152358.html