• 原型模式(克隆模式):浅谈浅克隆与深克隆


    克隆是什么?它的产生背景?

    当new的对象是多例的时候,new对象将会不断占据内存。特别是消耗内存的大对象,比如数据库连接等。平时运用的不多,只在spring等容器有见过,此处不多赘述,了解即可。

    浅克隆与深克隆是什么意思?通过案例逐步探讨。

    public class Star implements Cloneable,Serializable{
        private String name;
        private Date birthday;
    
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star(){}
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star(String name, Date birthday) {
        </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
        </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
        </span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">实现浅克隆</span>
    

    @Override
    protected Object clone() throws CloneNotSupportedException {
    return super.clone();
    }

    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getName() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> name;
    }
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setName(String name) {
        </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
    }
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Date getBirthday() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> birthday;
    }
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setBirthday(Date birthday) {
        </span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
    }
    

    }

    明星实体类-浅克隆
     1 public class Client {
     2     public static void main(String[] args) throws CloneNotSupportedException {
     3         Date date=new Date(1346545646556465131L);
     4         //new一个明星:杨洋
     5         Star  yangYang=new Star("杨洋",date);
     6         System.out.println(yangYang);
     7         System.out.println(yangYang.getName());
     8         System.out.println(yangYang.getBirthday());
     9         
    10         date.setTime(4685456456456465465L);
    11         System.out.println(yangYang.getBirthday());
    12         
    13         //克隆杨洋:满足你当明星的梦
    14         Star me=(Star) yangYang.clone();
    15         System.out.println(me);
    16         me.setName("周杰伦");
    17         System.out.println(me.getName());
    18         System.out.println(me.getBirthday());    
    19     }
    20 }

    问题:我们发现,当date改变的时候,克隆对象的date也随之改变。这个不难理解,因为原型对象改变,克隆对象也随之改变,克隆对象只是克隆了star对象,并没有去克隆star对象中的birthday对象。

    结论:浅克隆就是克隆对象直接引用原型对象。

    public class Star2 implements Cloneable{
        private String name;
        private Date birthday;
    
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star2(){}
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star2(String name, Date birthday) {
        </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
        </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
        </span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
    }
    </span><span style="color: #008000;">//</span><span style="color: #008000;">实现深克隆</span>
    

    @Override
    protected Object clone() throws CloneNotSupportedException {
    Object obj
    = super.clone();

        Star2 s</span>=<span style="color: #000000;">(Star2)obj;
        s.birthday</span>=(Date) <span style="color: #0000ff;">this</span><span style="color: #000000;">.birthday.clone();
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> obj;
    }
    
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getName() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> name;
    }
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setName(String name) {
        </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
    }
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Date getBirthday() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> birthday;
    }
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setBirthday(Date birthday) {
        </span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
    }
    

    }

    明星实体类-深克隆
     1 public class Client2 {
     2     public static void main(String[] args) throws CloneNotSupportedException {
     3         Date date=new Date(1346545646556465131L);
     4         //new一个明星:杨洋
     5         Star2  yangYang=new Star2("杨洋",date);
     6         Star2 me=(Star2) yangYang.clone();//深克隆里面的birthday对象是一个新对象
     7         
     8         System.out.println(yangYang);
     9         System.out.println(yangYang.getName());
    10         System.out.println(yangYang.getBirthday());
    11         
    12         date.setTime(4685456456456465465L);
    13         System.out.println(yangYang.getBirthday());
    14         
    15         
    16         System.out.println(me);
    17         me.setName("周杰伦");
    18         System.out.println(me.getName());
    19         System.out.println(me.getBirthday());        
    20     }
    21 }

     

    问题:我们发现,当date改变的时候,克隆对象的bitthday并没有随之改变。通过实体类可知,当克隆对象的时候,随之也去克隆了实体类里面的引用对象,即克隆对象的birthday是一个new的对象。

    结论:深克隆就是递归克隆出原型对象里的所有引用对象。

  • 相关阅读:
    【深度学习系列1】 深度学习在腾讯的平台化和应用实践
    js复制button在ie下的解决方式
    兔子--Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK
    UART串口协议基础1
    高校站点群建设方案简单介绍
    oracle10G之前介质下载地址【珍藏版】
    程序猿打新总结 6月份 新股申购秘籍
    斯坦福IOS开发第五课(第一部分)
    O2O领域添新军,正品网加快布局的战略考量
    如风一样,飞翔------Day37
  • 原文地址:https://www.cnblogs.com/qiuyong/p/6917972.html
Copyright © 2020-2023  润新知