浅拷贝和深拷贝(java)

 拷贝:多用于prototype原型模式的复制。

         数据库连接池,将properties中的jdbc信息(user/password/url/port)等获取后赋值给jdbcData对象,然后将对象复制n份,连接数据库,创建连接池。

 浅拷贝:

复制对象指向,不复制值,除过基本类型.当有对象在里面时,修改原对象的值,会导致clone后的内容值也发生变化。因为指向不变。

如果一个对象中没有引用其它对象,String不算。可以使用浅拷贝。因为String每次会新创建而不会破坏克隆后对象的引用。
***   浅拷贝clone要implements Cloneable接口

深拷贝

对象指向及其值一起拷贝,(如果一个对象中引用了另一个对象,而另一个对象中没有再引用其它内容,可在拷贝时,将内部对象重新拷贝再赋给当前对象)。

要通过输出流输入流的形式对象需要序列化操作。

**** 深拷贝clone要implements Serializable接口,其内部对象也要串型化

以下为创建的示例:

  1 /**
  2  * 原型模式要实现克隆,必须实现Cloneable
  3  * 拷贝分深拷贝和
  4  * 浅拷贝:复制对象指向,不复制值,除过基本类型.当有对象在里面时,修改原对象的值,会导致clone后的内容值也发生变化。因为指向不变。
  5  *      如果一个对象中没有引用其它对象,String不算。可以使用浅拷贝。因为String每次会新创建而不会破坏克隆后对象的引用。
  6  *      浅拷贝clone要implements Cloneable接口
  7  * 深拷贝:对象指向及其值一起拷贝,(如果一个对象中引用了另一个对象,而另一个对象中没有再引用其它内容,可在拷贝时,将内部对象重新拷贝再赋给当前对象)。要通过输出流输入流的形式
  8  *      对象需要序列化操作。
  9  *      深拷贝clone要implements Serializable接口,其内部对象也要序列号
 10  * 
 11  * @author DennyZhao
 12  * @date 2017年6月13日
 13  * @version 1.0
 14  */
 15 public class PrototypeFactory implements Cloneable, Serializable{
 16 
 17     /**
 18      * 自动生成序列号
 19      */
 20     private static final long serialVersionUID = 1416969741781583897L;
 21     private String name;
 22     private String englishName;
 23     private String nickName;
 24     private int age;
 25     private AnimalFactory animal;
 26     
 27     public String getNickName() {
 28         return nickName;
 29     }
 30     public void setNickName(String nickName) {
 31         this.nickName = nickName;
 32     }
 33     public String getEnglishName() {
 34         return englishName;
 35     }
 36     public void setEnglishName(String englishName) {
 37         this.englishName = englishName;
 38     }
 39     public String getName() {
 40         return name;
 41     }
 42     public void setName(String name) {
 43         this.name = name;
 44     }
 45     
 46     public int getAge() {
 47         return age;
 48     }
 49     public void setAge(int age) {
 50         this.age = age;
 51     }
 52     public AnimalFactory getAnimal() {
 53         return animal;
 54     }
 55     public void setAnimal(AnimalFactory animal) {
 56         this.animal = animal;
 57     }
 58     @Override
 59     public String toString() {
 60         return "PrototypeFactory [name=" + name + ", englishName="
 61                 + englishName + ", nickName=" + nickName + ", age=" + age
 62                 + ", animal=" + animal + "]";
 63     }
 64     
 65     /**
 66      * 浅拷贝
 67      */
 68     public PrototypeFactory clone() throws CloneNotSupportedException{
 69         return (PrototypeFactory)super.clone();
 70     }
 71     
 72     /**
 73      * 这种拷贝只能针对对象内的对象内都是基本数据类型才可以。且内部对象也具有克隆方法
 74      */
 75     public PrototypeFactory clone2() throws CloneNotSupportedException{
 76         PrototypeFactory pro = (PrototypeFactory)super.clone();
 77         //pro.animal = (PrototypeFactory)pro.animal.clone;
 78         return pro;
 79     }
 80     
 81     /**
 82      * 深拷贝
 83      */
 84     public PrototypeFactory deepClone(){
 85         ByteArrayOutputStream os = new ByteArrayOutputStream();
 86         ObjectOutputStream oos = null;
 87         ObjectInputStream ois = null;
 88         PrototypeFactory pro = null;
 89         try {
 90             oos = new ObjectOutputStream(os);
 91             oos.writeObject(this);
 92             ois = new ObjectInputStream(new ByteArrayInputStream(os.toByteArray()));
 93             pro = (PrototypeFactory)ois.readObject();
 94         } catch (ClassNotFoundException e) {
 95                 e.printStackTrace();
 96         } catch (IOException e) {
 97             e.printStackTrace();
 98         }
 99         return pro;
100     }
101     
102 }
ProtoTypeFactory

测试示例:

 1 public class TestProtoType {
 2 
 3     public static void main(String[] args) throws CloneNotSupportedException {
 4         //原型模式
 5         PrototypeFactory protoFactory = new PrototypeFactory();
 6         protoFactory.setEnglishName("DennyZhao");
 7         protoFactory.setName("~~~~强~~");
 8         protoFactory.setNickName("~~王~~");
 9         protoFactory.setAge(10);
10         Rabit rabit22 = new Rabit();
11         rabit22.getHeader("A", 2, "B");
12         protoFactory.setAnimal(rabit22);
13         PrototypeFactory cloneProto = protoFactory.clone();
14         PrototypeFactory cloneDeep = protoFactory.deepClone();
15         System.out.println("protoFactory:--" + protoFactory.toString());
16         System.out.println("cloneProto:---" + cloneProto.toString());
17         System.out.println("cloneDeep:---" + cloneDeep.toString());
18         // 修改原数据参数
19         protoFactory.setEnglishName("Denny....");
20         protoFactory.setAge(8);
21         ((Rabit)protoFactory.getAnimal()).getHeader("C", 3, "D");
22         System.out.println("2protoFactory:--" + protoFactory.toString());
23         System.out.println("2cloneProto:---" + cloneProto.toString());
24         System.out.println("2cloneDeep:---" + cloneDeep.toString());
25         System.out.println("3protoFactory---" + ((Rabit)protoFactory.getAnimal()).getHeader());
26         System.out.println("3cloneProto---" + ((Rabit)cloneProto.getAnimal()).getHeader());
27         System.out.println("3cloneDeep---" + ((Rabit)cloneDeep.getAnimal()).getHeader());
28 
29     }
TestPrototype

运行结果:

1 protoFactory:--PrototypeFactory [name=~~~~强~~, englishName=DennyZhao, nickName=~~王~~, age=10, animal=pattern.creation.factory.animal.Rabit@a57993]
2 cloneProto:---PrototypeFactory [name=~~~~强~~, englishName=DennyZhao, nickName=~~王~~, age=10, animal=pattern.creation.factory.animal.Rabit@a57993]
3 cloneDeep:---PrototypeFactory [name=~~~~强~~, englishName=DennyZhao, nickName=~~王~~, age=10, animal=pattern.creation.factory.animal.Rabit@17327b6]
4 2protoFactory:--PrototypeFactory [name=~~~~强~~, englishName=Denny...., nickName=~~王~~, age=8, animal=pattern.creation.factory.animal.Rabit@a57993]
5 2cloneProto:---PrototypeFactory [name=~~~~强~~, englishName=DennyZhao, nickName=~~王~~, age=10, animal=pattern.creation.factory.animal.Rabit@a57993]
6 2cloneDeep:---PrototypeFactory [name=~~~~强~~, englishName=DennyZhao, nickName=~~王~~, age=10, animal=pattern.creation.factory.animal.Rabit@17327b6]
7 3protoFactory---C3D
8 3cloneProto---C3D
9 3cloneDeep---A2B
Result

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

内容借鉴:(Java中的深拷贝(深复制)和浅拷贝(浅复制)http://www.cnblogs.com/shuaiwhu/archive/2010/12/14/2065088.html

以上,为个人总结,如有写的不当之处,还望指正。

                                                                    -----------DennyZhao

原文地址:https://www.cnblogs.com/DennyZhao/p/7016528.html