zoukankan      html  css  js  c++  java
  • Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的。

      下面来看一个关于引用的例子。

      

    package referenceCopy;
    // 一个文件中允许有多个类,但是public类型的类只能有一个
    class Basic {
    private int aInt = 0;
    public int getAInt() {
    return aInt;
    }
    public void setAInt(int int1) {
    aInt =int1;
    }
    public void changeInt() {
    this.aInt = 1;
    }
    }
    public class Children {
    // int char double 等基本类型都是按照值传递的,
    // 除此之外的其他类型都是按照引用进行传递的。
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Basic b = new Basic();
    Basic a = b;
    b.changeInt();
    System.out.println(b.getAInt());
    System.out.println(a.getAInt());
    }

    }

    输出的结果为1,1

    究其原因是a和b的指向同一个引用。

    那么如何变成两个引用呢,我们提出了浅复制和深复制。

    首先我们来看浅复制

    package referenceCopy;

    import java.util.Date;
    // 一个文件中允许有多个类,但是public类型的类只能有一个
    class BasicA implements Cloneable{
    private int aInt = 0;

    private Date birth = new Date();

    public Date getBirth() {
    return birth;
    }
    public void setBirth(Date birth) {
    this.birth = birth;
    }
    public void changeBirth() {
    this.birth.setMonth(1);
    }
    public int getAInt() {
    return aInt;
    }
    public void setAInt(int int1) {
    aInt =int1;
    }
    public void changeInt() {
    this.aInt = 1;
    }
    // 改写clone方法
    public Object clone() {
    Object o = null;
    try {
    o = (BasicA)super.clone();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return o;
    }
    }
    public class WeakChildrenReferneceCopy {
    // int char double 等基本类型都是按照值传递的,
    // 除此之外的其他类型都是按照引用进行传递的。
    // 相对于Children类,该类采用了浅复制的方法来进行复制。
    // 基本的数据类型变量已经全部复制了进来,但是具体对象的改变并未改变
    public static void main(String[] args) {
    BasicA b = new BasicA();
    BasicA a = (BasicA)b.clone();
    b.changeInt();
    b.changeBirth();
    // 由此可见,浅复制只复制了简单的数据类型,
    // 对于复杂的数据类型并未进行复制
    System.out.println(a.getAInt());
    System.out.println(b.getAInt());
    System.out.println(b.getBirth());
    System.out.println(a.getBirth());
    }

    }

    输出的结果如下所示:

    0

    1
    Mon Feb 06 14:45:47 CST 2017
    Mon Feb 06 14:45:47 CST 2017

    由结果可以看出,浅复制并未改变其他对象的引用。

    由此,我们提出了深复制

    package referenceCopy;


    import java.util.Date;
    //一个文件中允许有多个类,但是public类型的类只能有一个
    class BasicB implements Cloneable{
    private int aInt = 0;

    private Date birth = new Date();

    public Date getBirth() {
    return birth;
    }
    public void setBirth(Date birth) {
    this.birth = birth;
    }
    public void changeBirth() {
    this.birth.setMonth(1);
    }
    public int getAInt() {
    return aInt;
    }
    public void setAInt(int int1) {
    aInt =int1;
    }
    public void changeInt() {
    this.aInt = 1;
    }
    // 改写clone方法
    public Object clone() {
    // 强复制需要将返回的复制对象改变为自己需要的对象
    BasicB o = null;
    try {
    o = (BasicB)super.clone();
    } catch (CloneNotSupportedException e) {
    e.printStackTrace();
    }
    o.birth = (Date)this.getBirth().clone();
    return o;
    }
    }
    public class StrongChildrenReferenceCopy {
    public static void main(String[] args) {
    BasicB a = new BasicB();
    BasicB b = (BasicB) a.clone();
    b.changeInt();
    b.changeBirth();
    System.out.println(a.getAInt());
    System.out.println(b.getAInt());
    System.out.println(a.getBirth());
    System.out.println(b.getBirth());
    }

    }

    运行结果如下:

    0
    1
    Thu Jul 06 14:55:13 CST 2017
    Mon Feb 06 14:55:13 CST 2017

    由上处进行了标红的地方可以看出两者在进行复制时的不同之处。

    浅复制:被复制的对象的所有 变量都含有与原来对象相同的值,而所有对其他对象的引用仍然指向原来对象相同的值。换言之,浅复制只复制自己考虑的对象,未复制它所引用的对象。

    深复制:被复制对象的所有变量都含有与原来对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制的新对象,而不是原有的那些被引用的对象,换言之,深复制把复制对象 所引用的对象都复制了一遍。

  • 相关阅读:
    springboot整合mybatis实现增删改查小案例
    浅谈Nginx负载均衡原理与实现
    使用Cordova框架把Webapp封装成Hybrid App实践——Android篇
    ActiveMQ结合WebScoket应用例子以及介绍
    个人简介
    C#中的属性,字段,变量
    Aspose.Words 直接写response导出docx文档显示文件已损坏需要修复的解决办法
    System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(string, string)已过时的解决办法
    Aspose.Words:如何添加另一个WORD文档中的Node对象
    基于CPS变换的尾递归转换算法
  • 原文地址:https://www.cnblogs.com/Elliott-Su-Faith-change-our-life/p/7126388.html
Copyright © 2011-2022 走看看