2014-02-14 11:27:33 

声明:本文不仅是本人自己的成果,有些东西取自网上各位大神的思想,虽不能一一列出,但在此一并感谢!

原型模式,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。在Java中,复制对象是通过clone()实现的,调用的是Objectclone()方法,而在Object类中,clone()native。在这儿,我将结合对象的浅复制和深复制来说一下,首先需要了解对象深、浅复制的概念:

   浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

   深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

此处,写一个深、浅复制的例子:

Prototype.java

 

 1 package com.david.prototype;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.ByteArrayOutputStream;
 5 import java.io.IOException;
 6 import java.io.ObjectInputStream;
 7 import java.io.ObjectOutputStream;
 8 import java.io.Serializable;
 9 
10 public class Prototype implements Cloneable, Serializable {
11 
12     private static final long serialVersionUID = 1L;
13     private String string;
14 
15     private SerializableObject obj;
16 
17     /* 浅复制 */
18     public Object clone() throws CloneNotSupportedException {
19         Prototype proto = (Prototype) super.clone();
20         return proto;
21     }
22 
23     /* 深复制 */
24     public Object deepClone() throws IOException, ClassNotFoundException {
25 
26         /* 写入当前对象的二进制流 */
27         ByteArrayOutputStream bos = new ByteArrayOutputStream();
28         ObjectOutputStream oos = new ObjectOutputStream(bos);
29         oos.writeObject(this);
30 
31         /* 读出二进制流产生的新对象 */
32         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
33         ObjectInputStream ois = new ObjectInputStream(bis);
34         return ois.readObject();
35     }
36 
37     public String getString() {
38         return string;
39     }
40 
41     public void setString(String string) {
42         this.string = string;
43     }
44 
45     public SerializableObject getObj() {
46         return obj;
47     }
48 
49     public void setObj(SerializableObject obj) {
50         this.obj = obj;
51     }
52 }
53 
54 class SerializableObject implements Serializable {
55     private static final long serialVersionUID = 1L;
56 }

 

MainTest.java

 1 package com.david.prototype;
 2 
 3 import java.io.IOException;
 4 
 5 public class MainTest {
 6 
 7     public static void main(String[] args) {
 8         Prototype pt = new Prototype();
 9         pt.setString("Dawei");
10         pt.setObj(new SerializableObject());
11         System.out.println("pt = " + pt);
12         System.out.println("pt.getString = " + pt.getString());
13         System.out.println("pt.getObj = " + pt.getObj());
14         System.out.println("=============================================");
15         try {
16             Prototype pt_clone = (Prototype) pt.deepClone();
17             System.out.println("pt = " + pt_clone);
18             System.out.println("pt.getString = " + pt_clone.getString());
19             System.out.println("pt.getObj = " + pt_clone.getObj());
20         } catch (IOException e) {
21             e.printStackTrace();
22         } catch (ClassNotFoundException e) {
23             e.printStackTrace();
24         }/* catch (CloneNotSupportedException e) {
25             e.printStackTrace();
26         }*/
27     }
28 
29 }

注意红色代码,我们可以更换方法,分别调用深、浅两种clone方法,打出的log如下:

浅克隆:

pt = com.david.prototype.Prototype@3ce53108
pt.getString = Dawei
pt.getObj = com.david.prototype.SerializableObject@6af62373
=============================================
pt = com.david.prototype.Prototype@459189e1
pt.getString = Dawei
pt.getObj = com.david.prototype.SerializableObject@6af62373

看红色部分,打出来的对象hashcode是一样的。

深克隆:

pt = com.david.prototype.Prototype@2e6e1408
pt.getString = Dawei
pt.getObj = com.david.prototype.SerializableObject@3ce53108
=============================================
pt = com.david.prototype.Prototype@7ecd2c3c
pt.getString = Dawei
pt.getObj = com.david.prototype.SerializableObject@5013582d

看红、绿色部分,显然不一样,这说明克隆前后的SerializableObject obj对象不是同一个对象。

 

 

 posted on 2014-02-14 11:36  wlrhnh  阅读(640)  评论(0编辑  收藏  举报