java 浅拷贝和深拷贝

Java中的对象拷贝指的是将一个对象的所有属性拷贝到另一个有着相同类型的对象中去。举例说明:比如,对象A和对象B都属于类S,具有属性a和b。那么对对象A进行拷贝操作赋值给对象B就是:B.a=A.a;B.b=A.b。Java中的对象拷贝主要分为:浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。

浅拷贝

1、对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。2、对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。

省略get/set


/**
 * 拷贝的对象
 *
 * @author : yangdehong
 * @date : 2019/4/2 22:20
 */
public class CopyObject implements Cloneable {

    private Integer age;

    private String name;

    private Long money;

    public CopyObject() {
        this.age = 11;
        this.name = "央财";
        this.money = 99L;
    }

    @Override
    public String toString() {
        return "CopyObject{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }

    // 重写Object类的clone方法
    @Override
    public Object clone() {
        Object obj = null;
        //调用Object类的clone方法,返回一个Object实例
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }

}

/**
* 拷贝的对象
* @author : yangdehong
* @date : 2019/4/2 22:21
*/
public class ParentCopyObject implements Cloneable {

    private CopyObject copyObject;

    private String email;

    private Integer high;

    @Override
    public String toString() {
        return "ParentCopyObject{" +
                "copyObject=" + copyObject +
                ", email='" + email + '\'' +
                ", high=" + high +
                '}';
    }

    // 重写Object类的clone方法
    @Override
    public Object clone() {
        Object obj = null;
        //调用Object类的clone方法,返回一个Object实例
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }

}

/**
* 浅拷贝
* @author : yangdehong
* @date : 2019/4/2 21:16
*/
public class ShallowCopyMain {

    public static void main(String[] args) {
        CopyObject copyObject = new CopyObject();
        ParentCopyObject parentCopyObject = new ParentCopyObject();
        parentCopyObject.setCopyObject(copyObject);

        ParentCopyObject parentCopyObject2 = (ParentCopyObject) parentCopyObject.clone();

        parentCopyObject2.getCopyObject().setAge(12);
        parentCopyObject2.setEmail("123@qq.com");


        System.out.println(parentCopyObject);
        System.out.println(parentCopyObject2);
    }

}

结果:copyObject的age两个都修改掉了;email只修改了自己

ParentCopyObject{copyObject=CopyObject{age=12, name='央财', money=99}, email='null', high=null}
ParentCopyObject{copyObject=CopyObject{age=12, name='央财', money=99}, email='123@qq.com', high=null}

深拷贝

对于深拷贝来说,不仅要复制对象的所有基本数据类型的成员变量值,还要为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象图进行拷贝!
两个对象多实现implements Serializable

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
* 深拷贝
* @author : yangdehong
* @date : 2019/4/2 23:00
*/
public class DeepCopyUtils {
    @SuppressWarnings("unchecked")
    public static <T> T copyObject(T src) {
        T dest;
        try {
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(src);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream in = new ObjectInputStream(byteIn);

            dest = (T) in.readObject();
        } catch (Exception ex) {
            ex.printStackTrace();
            dest = null;
        }
        return dest;
    }


}

public static void main(String[] args) {
//        shallowCopy();
        deepCopy();
    }

    public static void deepCopy() {
        CopyObject copyObject = new CopyObject();
        ParentCopyObject parentCopyObject = new ParentCopyObject();
        parentCopyObject.setCopyObject(copyObject);

        ParentCopyObject parentCopyObject2 = DeepCopyUtils.copyObject(parentCopyObject);

        parentCopyObject2.getCopyObject().setAge(12);
        parentCopyObject2.setEmail("123@qq.com");


        System.out.println(parentCopyObject);
        System.out.println(parentCopyObject2);
    }

结果::copyObject的age只修改了自己;email只修改了自己

ParentCopyObject{copyObject=CopyObject{age=11, name='央财', money=99}, email='null', high=null}
ParentCopyObject{copyObject=CopyObject{age=12, name='央财', money=99}, email='123@qq.com', high=null}

其他方式

上面的浅拷贝是clone的方式,还可以通过构造函数的方式;深拷贝是通过序列化的方式,深拷贝还能通过clone的方式,这里就不详细说明了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值