JAVA学习-深拷贝和浅拷贝的实现方式

在 Java 的学习过程,很多人在拷贝的时候,都习惯用 clone 方法直接拷贝,但有时候总会出现一些问题,看我举例:

先定义Person类存储个人信息:

class Person implements Cloneable{
    //姓名
    String name;
    //电话
    String phone;
    //性别
    String sex;

    public Person(String name, String phone, String sex) {
        super();
        this.name = name;
        this.phone = phone;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", phone=" + phone + ", sex=" + sex + "]";
    }

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

在定义用户类存储账号密码和个人信息:

class User implements Cloneable{

    //用户id
    int userid;
    //用户密码
    String password;
    //用户信息
    Person person;

    public User(int userid, String password, Person person) {
        super();
        this.userid = userid;
        this.password = password;
        this.person = person;
    }

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

    @Override
    public String toString() {
        return "User [userid=" + userid + ", password=" + password + ", person=" + person + "]";
    }
}

现在我们创建一个User类进行拷贝:

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person("yin", "1008611", "女");
        User user1 = new User(1, "123123", person);
        //对 user1 进行克隆
        User user2 = (User) user1.clone();

        //输出信息
        System.out.println(user1);
        System.out.println(user2);

        //对账号密码进行修改
        user2.userid = 2;
        user2.password = "112233";

        //输出信息
        System.out.println(user1);
        System.out.println(user2);

        //对 user1 用户信息进行修改
        user1.person.name = "xu";
        user1.person.phone = "106688";
        user1.person.sex = "男";

        //输出信息
        System.out.println(user1);
        System.out.println(user2);
    }
}

执行结果:

User [userid=1, password=123123, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=1, password=123123, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=1, password=123123, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=2, password=112233, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=1, password=123123, person=Person [name=xu, phone=106688, sex=男]]
User [userid=2, password=112233, person=Person [name=xu, phone=106688, sex=男]]

从执行结果可以看出,虽然我们拷贝了 user1,但当我们对 user1 中的 person 进行修改时,user2 的 person 信息也会跟着改变,像这种只拷贝了类的属性的方式,就称作 浅拷贝,因为我们只拷贝了对象本身,却没有拷贝对象包含的引用指向的对象,而 深拷贝 则是会对这些指向的对象一起拷贝。

看我对 User 类的 clone方法做个修改:

@Override
protected Object clone() throws CloneNotSupportedException {
    User user = (User) super.clone();
    user.person = (Person) person.clone();
    return user;
}

再看执行结果:

User [userid=1, password=123123, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=1, password=123123, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=1, password=123123, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=2, password=112233, person=Person [name=yin, phone=1008611, sex=女]]
User [userid=1, password=123123, person=Person [name=xu, phone=106688, sex=男]]
User [userid=2, password=112233, person=Person [name=yin, phone=1008611, sex=女]]

这样 user2 的个人信息就不会随 user1 个人信息改变而改变了,这种拷贝方式就是 深拷贝

注意:深拷贝 在遇到对象层级比较的大的对象时,性能消耗会很大,所以如果有比 深拷贝 更好的方式就采用更好的方式。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什巳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值