• 浅谈浅克隆(shallow clone)和 深克隆(deep clone)


    区别就在于是否对对象中的引用变量所指向的对象进行拷贝。

    1.浅克隆/浅复制/浅拷贝

      浅拷贝是指在拷贝对象时,对于基本数据类型的变量会重新复制一份,而对于引用类型的变量只是对引用进行拷贝,没有对引用指向的对象进行拷贝。

    2.深克隆/深复制/深拷贝

      深拷贝是指在拷贝对象时,同时会对引用指向的对象进行拷贝。

    示例代码:

      1 import java.util.Date;
      2 
      3 class Wife implements Cloneable {
      4     private String name;
      5     private Date birthday;
      6     
      7     public Wife(){
      8     }
      9     
     10     public Wife(String name, Date birthday) {
     11         this.name = name;
     12         this.birthday = birthday;
     13     }
     14 
     15     public Date getBirthday(){
     16         return birthday;
     17     }
     18     
     19     public String getName() {
     20         return name;
     21     }
     22     public void setName(String name) {
     23         this.name = name;
     24     }
     25 
     26     public Object clone() throws CloneNotSupportedException {
     27         return super.clone();
     28     }
     29 
     30     public String toString() {
     31         return "Wife [name=" + name + ", birthday=" + birthday + "]";
     32     }
     33     
     34 }
     35 
     36 class Husband implements Cloneable {
     37     private String name;
     38     private Wife wife;
     39     
     40     public Husband(){
     41     }
     42 
     43     public Husband(String name, Wife wife) {
     44         this.name = name;
     45         this.wife = wife;
     46     }
     47 
     48     public Wife getWife() {
     49         return wife;
     50     }
     51 
     52     public void setWife(Wife wife) {
     53         this.wife = wife;
     54     }
     55 
     56     public String getName() {
     57         return name;
     58     }
     59 
     60     public void setName(String name) {
     61         this.name = name;
     62     }
     63 
     64     /**
     65      * 浅克隆一个对象
     66      * @throws CloneNotSupportedException 
     67      */
     68     public Object shallowClone() throws CloneNotSupportedException {
     69         return super.clone();
     70     }
     71     /**
     72      * 利用串行化深克隆一个对象,把对象以及它的引用读到流里,在写入其他的对象
     73      * @return
     74      * @throws Exception
     75      */
     76     public Object deepClone() throws Exception {
     77         Husband husband = (Husband) super.clone();
     78         husband.wife = (Wife) this.wife.clone();
     79         return husband;
     80     }
     81 }
     82 
     83 public class Test {
     84     public static void main(String[] args) throws Exception{
     85         //浅克隆
     86         Wife w1 = new Wife("曹夫人", new Date());
     87         Husband h1 = new Husband("曹先生", w1);
     88         Husband h2 = (Husband) h1.shallowClone();
     89         
     90         System.out.println("原型对象:" + h1.getName() + "--" + h1.getWife());
     91         System.out.println("克隆对象:" + h2.getName() + "--" + h2.getWife());
     92         
     93         w1.setName("张夫人");
     94         
     95         System.out.println("
    --------------------------修改克隆对象的属性值后---------------------------
    ");
     96         
     97         System.out.println("原型对象:" + h1.getName() + "--" + h1.getWife());
     98         System.out.println("克隆对象:" + h2.getName() + "--" + h2.getWife());
     99         
    100         System.out.println("
    ---------------------------------------------------------------------
    ");
    101         
    102         //深克隆
    103         Wife w2 = new Wife("曹夫人", new Date());
    104         Husband h3 = new Husband("曹先生", w2);
    105         Husband h4 = (Husband) h3.deepClone();
    106         
    107         System.out.println("原型对象:" + h3.getName() + "--" + h3.getWife());
    108         System.out.println("克隆对象:" + h4.getName() + "--" + h4.getWife());
    109         
    110         w2.setName("张夫人");
    111         
    112         System.out.println("
    --------------------------修改克隆对象的属性值后---------------------------
    ");
    113         
    114         System.out.println("原型对象:" + h3.getName() + "--" + h3.getWife());
    115         System.out.println("克隆对象:" + h4.getName() + "--" + h4.getWife());
    116         
    117         
    118     }
    119 }

    控制台输出:

    原型对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    克隆对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    
    --------------------------修改克隆对象的属性值后---------------------------
    
    原型对象:曹先生--Wife [name=张夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    克隆对象:曹先生--Wife [name=张夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    
    ---------------------------------------------------------------------
    
    原型对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    克隆对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    
    --------------------------修改克隆对象的属性值后---------------------------
    
    原型对象:曹先生--Wife [name=张夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
    克隆对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018]
  • 相关阅读:
    RSA加密、解密、签名、验签的原理及方法
    typescript类
    typeScriptinterface和class区别
    Object.defineProperty
    vue源码学习实例挂载的实现
    typescript类型别名
    Spring.Day03.web集成
    Spring.Day04,数据响应方式
    MSSQL ( SQL Server )单用户模式的启用与停止(关闭)
    13.Redis数据迁移
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8145558.html
Copyright © 2020-2023  润新知