举例说明深拷贝和浅拷贝

概述

简单描述一下对象的实例化过程。

创建对象的时候,或者说在实例化对象的时候 Person 类有年龄和学生类

int age = 18;
Student stu1 = new Student();

比如此时创建一个 age 对象,一个Student 对象,在虚拟机中,会在堆中开一个对象空间,里面包含了对象的属性信息,当给基本数据类型赋值时,会将赋的值存储在堆中,然后在栈中会创建一个对象名保存着堆中数据的地址。简单说就是指向堆中的对象。给引用数据类型赋值时,会将赋的值存在方法区的常量池中,而堆保存的是方法区的地址,栈中同样保存的是堆中的地址。

拷贝

浅拷贝:浅拷贝会在堆上创建一个新的对象,不过,如果原对象内部的属性是引用数据类型的话,浅拷贝会直接赋值内部对象的引用地址,也就是说原对象和拷贝对象指向同一个对象。

深拷贝:深拷贝会完全赋值整个对象,包括这个对象的所有的内部对象。

举个通俗的例子

此时你的电脑桌面上有两个东西,一个是一个压缩包,里面有很多东西,比如图片压缩包等,还有一个是一款游戏的快捷方式。

浅拷贝,就像是你把快捷方式复制粘贴了一遍,无论你使用哪个都可以 XX!启动!,因为他们都是指向游戏本体程序的,属于两个对象指向同一个内部对象。

深拷贝,就像是你把压缩包复制了一遍,你不管将哪一个压缩包拷贝到U盘都可以在另一台电脑使用。因为两个都是独立的对象,只不过一模一样。

图片来源:JavaGuide 

实例代码

浅拷贝

/**
* 地址类
*
*/

@Data
public class Address implements Cloneable{

    private String name;

    @Override
    public Address clone() {
        try {
            return (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
/**
* 人类
*/

@Data
public class Person implements Cloneable {

    private Address address;

    @Override
    public Person clone() {
        try {
            return (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
/**
* 测试
*/ 
Person person1 = new Person();
Person clone = person1.clone();
System.out.println(person1.getAddress() == clone.getAddress());

输出为 true,表示两个对象的内部对象是同一个对象。

修改为深拷贝 ,我们将Person 类中的 Address 对象也进行了拷贝,相当于我不久将快捷方式也复制了一次,也将游戏的实际程序主体也进行了复制。

    @Override
    public Person clone() {
        try {
            Person person = (Person) super.clone();
            person.setAddress(person.getAddress().clone());
            return person;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
Person person = new Person(new Address());
Person clone = person.clone();
System.out.println(clone.getAddress() == person.getAddress());

输出为 false,说明内部对象已经不是同一个对象了,内部对象也被拷贝的一次。 

参考资料:Java 面试指南 | JavaGuide

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值