JAVA中的深拷贝与浅拷贝以及引用拷贝

JAVA中的深拷贝与浅拷贝以及引用拷贝

背景

最近在看JDK源码,看到集合的时候,大部分集合都继承了Cloneable,并且集合中的clone()调用Cloneable里面的clone(),并且注释里面有一句话是Returns a shallow copy of thisxxx,也就是浅拷贝

这让我不得不产生了下面的疑问

  • 什么是浅拷贝

  • 为什么集合用的是浅拷贝?

浅拷贝含义

被复制对象的所有属性都与原来的对象相同,且对象中对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

简而言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象

实例

public class Department implements Cloneable{
    private String name;
    private Integer num;

    public Department (String name, Integer num) {
        this.name = name;
        this.num = num;
    }

    public String getName () {
        return name;
    }

    public void setName (String name) {
        this.name = name;
    }

    public Integer getNum () {
        return num;
    }

    public void setNum (Integer num) {
        this.num = num;
    }
    
        @Override
    public String toString () {
        return "Department{" +
                "name='" + name + '\'' +
                ", num=" + num +
                '}';
    }
}
public class Company implements Cloneable {
    private String name;
    private String logo;
    private Department department;

    public Company (String name, String logo, Department department) {
        this.name = name;
        this.logo = logo;
        this.department = department;
    }

    public String getName () {
        return name;
    }

    public void setName (String name) {
        this.name = name;
    }

    public String getLogo () {
        return logo;
    }

    public void setLogo (String logo) {
        this.logo = logo;
    }

    public Department getDepartment () {
        return department;
    }

    public void setDepartment (Department department) {
        this.department = department;
    }


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

    public static void main (String[] args) throws CloneNotSupportedException {
        Department department = new Department ("人事部", 10001);
        Company company = new Company ("阿里", "1.png", department);
        Company company01 = (Company) company.clone ();
        System.out.println ("=======拷贝后=========");
        System.out.println (company01.getDepartment () == department);
        System.out.println (company01 == company);
		System.out.println (company01.getDepartment ().toString ());
    }
}

结果

=======拷贝后=========
true  
false
Department{name='人事部', num=10001}

所以对company进行浅拷贝之后,company和拷贝之后得到的company01里面的department其实是同一个对象

在这里插入图片描述

深拷贝含义

深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

简而言之,深拷贝把要复制的对象所引用的对象都复制了一遍。

public class Department implements Cloneable{
    private String name;
    private Integer num;

    public Department (String name, Integer num) {
        this.name = name;
        this.num = num;
    }

    public String getName () {
        return name;
    }

    public void setName (String name) {
        this.name = name;
    }

    public Integer getNum () {
        return num;
    }

    public void setNum (Integer num) {
        this.num = num;
    }

        @Override
    public String toString () {
        return "Department{" +
                "name='" + name + '\'' +
                ", num=" + num +
                '}';
    }

    @Override
    protected Object clone () throws CloneNotSupportedException {
        return super.clone ();
    }
}
public class Company implements Cloneable {
    private String name;
    private String logo;
    private Department department;

    public Company (String name, String logo, Department department) {
        this.name = name;
        this.logo = logo;
        this.department = department;
    }

    public String getName () {
        return name;
    }

    public void setName (String name) {
        this.name = name;
    }

    public String getLogo () {
        return logo;
    }

    public void setLogo (String logo) {
        this.logo = logo;
    }

    public Department getDepartment () {
        return department;
    }

    public void setDepartment (Department department) {
        this.department = department;
    }


    @Override
    protected Object clone () throws CloneNotSupportedException {
        Company company = (Company)super.clone ();
        company.setDepartment ((Department)company.getDepartment ().clone());
        return company;
    }

    public static void main (String[] args) throws CloneNotSupportedException {
        Department department = new Department ("人事部", 10001);
        Company company = new Company ("阿里", "1.png", department);
        Company company01 = (Company) company.clone ();
        System.out.println ("=======拷贝后=========");
        System.out.println (company01.getDepartment () == department);
        System.out.println (company01 == company);
		System.out.println (company01.getDepartment ().toString ());
    }
}

结果

=======拷贝后=========
false
false
Department{name='人事部', num=10001}

所以对company进行深拷贝之后,company和拷贝之后得到的company01里面的department不是同一个对象,只是拥有同样的name和num属性的两个不同对象

在这里插入图片描述
深拷贝和浅拷贝都是对象拷贝

那有没有引用拷贝呢?

当然有

引用拷贝

创建一个指向对象的引用变量的拷贝。

Department department = new Department ("人事部", 10001);
Company company = new Company ("阿里", "1.png", department);
Company company01 = company;
System.out.println ("=======拷贝后=========");
System.out.println (company01.getDepartment () == department);
System.out.println (company01 == company);
System.out.println (company01.getDepartment ().toString ());

结果

=======拷贝后=========
true
true
Department{name='人事部', num=10001}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值