java克隆--浅拷贝和深拷贝

本文介绍了Java中克隆的概念,区分浅拷贝(只复制基本类型,不复制引用对象)和深拷贝(递归复制所有引用,包括引用对象)。还提到通过实现Cloneable接口和序列化来实现深拷贝的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、克隆

克隆的含义就是:根据一个类复制另一个类,这个新的类内容与源类是相同的,但是内存地址不同。

在java中使用克隆的方式是:实现Cloneable 接口并实现clone()方法即可,一般是super.clone(),因为Cloneable是一个空接口

2、浅拷贝

克隆得到的类,只克隆了基本数据类型的数据,而没有克隆引用数据类型的数据,比如类中引用的对象等。具体如下面示例:

public class MSTest {

    public static void main(String[] args) throws Exception{
        UserInfo userInfo,userInfo2,userInfo3;
        userInfo = new UserInfo();
        userInfo2 = (UserInfo) userInfo.clone();

        //克隆后两个对象内容相等但在内存中的位置不同
        System.out.println(userInfo == userInfo2);      //false
        System.out.println(userInfo.equals(userInfo2));//true

        //克隆后两对象中的引用类型是同一个,因此没有完全克隆
        System.out.println(userInfo.getBody() == userInfo2.getBody());   //true
        System.out.println(userInfo.getBody().equals(userInfo2.getBody())); //true

    }
}

@Data
class UserInfo implements Cloneable{
    private String name;
    private String address;
    private int age;
    private Body body = new Body("111","222");

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserInfo userInfo = (UserInfo) o;
        return age == userInfo.age &&
                Objects.equal(name, userInfo.name) &&
                Objects.equal(address, userInfo.address) &&
                Objects.equal(body, userInfo.body);
    }

}

@Data
class Body{
    private String heigh;
    private String weight;

    Body(String heigh,String weight){
        this.heigh = heigh;
        this.weight = weight;
    }
}

3、深拷贝

深拷贝会创建一个新的对象,并复制原对象的所有内容。对于引用数据类型,深拷贝会递归地复制其所有引用,直到基本类型,然后复制这些基本类型的值。
实现方式:
1、递归调用clone()

@Override
protected Object clone() throws CloneNotSupportedException {
    UserInfo userInfo = (UserInfo) super.clone();
//获取了对象的基础类型,若对象中有引用类型,则它的clone()中也需要去获取这个引用的clone()
    userInfo.body = (Body) userInfo.getBody().clone();
    return userInfo;
}

@Data
class Body implements Cloneable{
    private String heigh;
    private String weight;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    Body(String heigh, String weight){
        this.heigh = heigh;
        this.weight = weight;
    }
}

2、通过序列化获取

@Data
class UserInfo implements Cloneable,Serializable {
    private String name;
    private String address;
    private int age;
    private Body body = new Body("111","222");


    protected Object clone() throws CloneNotSupportedException {
        UserInfo userInfo = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            userInfo = (UserInfo) ois.readObject();
        }catch (Exception e){
            e.printStackTrace();
        }
        return userInfo;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserInfo userInfo = (UserInfo) o;
        return age == userInfo.age &&
                Objects.equal(name, userInfo.name) &&
                Objects.equal(address, userInfo.address) &&
                Objects.equal(body, userInfo.body);
    }
}

4、深拷贝与浅拷贝区别

浅拷贝不拷贝引用类型,只是复制了对象的引用,而不进行创建对象。深拷贝会递归复制其所有引用,直到基本类型,然后复制这些基本类型的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值