java中的浅拷贝与深拷贝

java中的浅拷贝与深拷贝

浅拷贝

实现方法:要拷贝的类,实现Cloneable接口,然后重写clone方法,即可实现浅拷贝。

但缺点在于,如果该类的成员包含其他类,则其他类并没有被拷贝,只是拷贝了一个引用对象,其指向的地址和之前的对象一致,因此,修改people1的宠物信息,people的宠物信息也变了。

package cn.flycold.深浅拷贝.浅拷贝;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author liyutong03
 * @description
 * @date 2019/10/30
 * Copyright (C) 2015 Meituan
 * All rights reserved
 */
public class 浅拷贝 {
    public static void main(String []args) throws CloneNotSupportedException{
        Pet pet = Pet.builder().pAge(2).pName("包子").build();
        People people = People.builder().age(23).name("lyt").pet(pet).build();
        People people1 = people.clone();
        System.out.println("people :" + people);
        System.out.println("people1:" + people1);
        people1.setName("zzz");
        people1.setAge(19);
        people1.getPet().setPName("馒头");
        people1.getPet().setPAge(3);
        System.out.println("after change people1");
        System.out.println("people :" + people);
        System.out.println("people1:" + people1);
    }
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class People implements Cloneable{
    private int age;
    private String name;
    private Pet pet;

    @Override
    public People clone() throws CloneNotSupportedException{
        return (People) super.clone();
    }
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class Pet{
    private String pName;
    private int pAge;
}

深拷贝

我们可以用两种方法实现深拷贝

实现Cloneable接口

对要拷贝的类,以及其引用的类,都实现Cloneable接口,并重写clone方法。

注意,包含其他类的类,需要注意clone方法的实现,需要手动调用包含的类的clone方法

这种方法的劣势在于,层级太多的话代码会很麻烦。

实现Serializable接口

Serializable接口是用来序列化和反序列化的,我们用输出流将员对象序列化为字节,在用输入流将字节反序列化为对象,就实现了深拷贝,好处是简单,我们只需在类上标注其实现 Seriablizeable接口,注意,包含的类也要标注,即可。

package cn.flycold.深浅拷贝.深拷贝;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.*;

/**
 * @author liyutong03
 * @description
 * @date 2019/10/30
 * Copyright (C) 2015 Meituan
 * All rights reserved
 */
public class 深拷贝 {
    public static void main(String []args) throws Exception{
        Pet pet = Pet.builder().pAge(2).pName("包子").build();
        People people = People.builder().age(23).name("lyt").pet(pet).build();
        // Cloneable实现深拷贝
        // People people1 = people.clone();

        // Serializable实现深拷贝
        People people1 = (People) deepCopy(people);
        System.out.println("people :" + people);
        System.out.println("people1:" + people1);
        people1.setName("zzz");
        people1.setAge(19);
        people1.getPet().setPName("馒头");
        people1.getPet().setPAge(3);
        System.out.println("after change people1");
        System.out.println("people :" + people);
        System.out.println("people1:" + people1);
    }

    public static Object deepCopy(Object object) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream);
        oos.writeObject(object);

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
        return ois.readObject();


    }
}



@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class People implements Cloneable, Serializable {
    private int age;
    private String name;
    private Pet pet;

    @Override
    public People clone() throws CloneNotSupportedException{
        People people =  (People) super.clone();
        people.setPet(people.getPet().clone());
        return people;
    }
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class Pet implements Cloneable, Serializable{
    private String pName;
    private int pAge;

    @Override
    public Pet clone() throws CloneNotSupportedException{
        return (Pet)super.clone();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值