• Java 深复制和浅复制


      浅复制是指复制对象时仅仅复制对象本身(包括对象中的基本变量),而不复制对象包含的引用指向的对象。深复制不仅复制对象本身,而且复制对象包含的引用指向的对象。

      复制对象时需要调用Object类的clone方法:

    1 protected native Object clone() throws CloneNotSupportedException;

      步骤:

      1 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法时会抛出CloneNotSupportedException异常) 。而该接口为标记接口(不含任何抽象方法)。

      2 重写clone()方法,访问修饰符设为public,通过调用super.clone()方法得到需要的复制对象。

      

      浅复制

     1 class Address  {
     2     private String add;
     3 
     4     public String getAdd() {
     5         return add;
     6     }
     7 
     8     public void setAdd(String add) {
     9         this.add = add;
    10     }
    11     
    12 }
    13 
    14 class Student implements Cloneable{
    15     private int number;
    16 
    17     private Address addr;
    18     
    19     public Address getAddr() {
    20         return addr;
    21     }
    22 
    23     public void setAddr(Address addr) {
    24         this.addr = addr;
    25     }
    26 
    27     public int getNumber() {
    28         return number;
    29     }
    30 
    31     public void setNumber(int number) {
    32         this.number = number;
    33     }
    34     
    35     @Override
    36     public Object clone() {
    37         Student stu = null;
    38         try{
    39             stu = (Student)super.clone();
    40         }catch(CloneNotSupportedException e) {
    41             e.printStackTrace();
    42         }
    43         return stu;
    44     }
    45 }
    46 public class Test {
    47     
    48     public static void main(String args[]) {
    49         
    50         Address addr = new Address();
    51         addr.setAdd("杭州市");
    52         Student stu1 = new Student();
    53         stu1.setNumber(123);
    54         stu1.setAddr(addr);
    55         
    56         Student stu2 = (Student)stu1.clone();
    57         
    58         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
    59         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
    60 
    61         addr.setAdd("西湖区");
    62         
    63         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
    64         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
    65     }
    66 }

      结果如下:

    1 学生1:123,地址:杭州市  
    2 学生2:123,地址:杭州市
    3 学生1:123,地址:杭州市  
    4 学生2:123,地址:杭州市  
    5 学生1:123,地址:西湖区  
    6 学生2:123,地址:西湖区

      两个学生的地址都改变了。原因是浅复制只是复制了addr变量的引用,并没有真正地开辟另一块空间来存储地址对象。

      

      深复制

     1 class Address implements Cloneable {
     2     private String add;
     3 
     4     public String getAdd() {
     5         return add;
     6     }
     7 
     8     public void setAdd(String add) {
     9         this.add = add;
    10     }
    11     
    12     @Override
    13     public Object clone() {
    14         Address addr = null;
    15         try{
    16             addr = (Address)super.clone();
    17         }catch(CloneNotSupportedException e) {
    18             e.printStackTrace();
    19         }
    20         return addr;
    21     }
    22 }
    23 
    24 class Student implements Cloneable{
    25     private int number;
    26 
    27     private Address addr;
    28     
    29     public Address getAddr() {
    30         return addr;
    31     }
    32 
    33     public void setAddr(Address addr) {
    34         this.addr = addr;
    35     }
    36 
    37     public int getNumber() {
    38         return number;
    39     }
    40 
    41     public void setNumber(int number) {
    42         this.number = number;
    43     }
    44     
    45     @Override
    46     public Object clone() {
    47         Student stu = null;
    48         try{
    49             stu = (Student)super.clone();    //浅复制
    50         }catch(CloneNotSupportedException e) {
    51             e.printStackTrace();
    52         }
    53         stu.addr = (Address)addr.clone();    //深度复制
    54         return stu;
    55     }
    56 }
    57 public class Test {
    58     
    59     public static void main(String args[]) {
    60         
    61         Address addr = new Address();
    62         addr.setAdd("杭州市");
    63         Student stu1 = new Student();
    64         stu1.setNumber(123);
    65         stu1.setAddr(addr);
    66         
    67         Student stu2 = (Student)stu1.clone();
    68         
    69         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
    70         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
    71         
    72         addr.setAdd("西湖区");
    73         
    74         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
    75         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
    76     }
    77 }

      结果如下:

    1 学生1:123,地址:杭州市
    2 学生2:123,地址:杭州市
    3 学生1:123,地址:西湖区
    4 学生2:123,地址:杭州市

      

      参考资料

      java.util.ArrayList.clone是不是彻底的克隆

      Java如何复制对象

  • 相关阅读:
    windows 程序设计自学:窗口正中显示Hello,World
    为网站图片增加延迟加载功能,提升用户体验
    线性表顺序存储
    sys.stdout sys.stderr的用法
    python 跳出嵌套循环方法
    * 与 ** 在调用函数时的作用
    twisted 学习笔记二:创建一个简单TCP客户端
    给命令行上色
    __new__ 的简单应用
    网友对twisted deferr的理解
  • 原文地址:https://www.cnblogs.com/WJQ2017/p/7601784.html
Copyright © 2020-2023  润新知