ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

死磕Java面试系列:深拷贝与浅拷贝的实现原理

2022-11-07 12:03:27  阅读:294  来源: 互联网

标签:java 函数 学习 系统 语言 平台 方法 安装 QML c++ 数据


深拷贝与浅拷贝的问题,也是面试中的常客。虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝。其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入剖析一下深拷贝与浅拷贝的实现原理,并手把手教你怎么优雅的实现深拷贝。

1. 什么是深拷贝与浅拷贝

浅拷贝: 只拷贝栈内存中的数据,不拷贝堆内存中数据。

深拷贝: 既拷贝栈内存中的数据,又拷贝堆内存中的数据。

2. 浅拷贝的实现原理

由于浅拷贝只拷贝了栈内存中数据,栈内存中存储的都是基本数据类型,堆内存中存储了数组、引用数据类型等。

使用代码验证一下:

想要实现clone功能,需要实现 Cloneable 接口,并重写 clone 方法。

  1. 先创建一个用户类
// 用户的实体类,用作验证
public class User implements Cloneable {
    private String name;
    
    // 每个用户都有一个工作
    private Job job;

    public String getName() {
        return name;
    }

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

    public Job getJob() {
        return job;
    }

    public void setJob(Job job) {
        this.job = job;
    }


    @Override
    public User clone() throws CloneNotSupportedException {
        User user = (User) super.clone();
        return user;
    }
}
  1. 再创建一个工作类
// 工作的实体类,并没有实现Cloneable接口
public class Job {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
  1. 测试浅拷贝
/**
 * @author 一灯架构
 * @apiNote Java浅拷贝示例
 **/
public class Demo {

    public static void main(String[] args) throws CloneNotSupportedException {
        // 1. 创建用户对象,{"name":"一灯架构","job":{"content":"开发"}}
        User user1 = new User();
        user1.setName("一灯架构");
        Job job1 = new Job();
        job1.setContent("开发");
        user1.setJob(job1);

        // 2. 拷贝用户对象,name修改为"张三",工作内容修改"测试"
        User user2 = user1.clone();
        user2.setName("张三");
        Job job2 = user2.getJob();
        job2.setContent("测试");
        
        // 3. 输出结果
        System.out.println("user原对象= " + user1);
        System.out.println("user拷贝对象= " + user2);
    }

}

输出结果:

user原对象= {"name":"一灯架构","job":{"content":"测试"}}
user拷贝对象= {"name":"张三","job":{"content":"测试"}}

从结果中可以看出,对象拷贝把name修改为”张三“,原对象并没有变,name是String类型,是基本数据类型,存储在栈内存中。对象拷贝了一份新的栈内存数据,修改并不会影响原对象。

然后对象拷贝把Job中content修改为”测试“,原对象也跟着变了,原因是Job是引用类型,存储在堆内存中。对象拷贝和原对象指向的同一个堆内存的地址,所以修改会影响到原对象。

3. 深拷贝的实现原理

深拷贝是既拷贝栈内存中的数据,又拷贝堆内存中的数据。

实现深拷贝有很多种方法,下面就详细讲解一下,看使用哪种方式更方便快捷。

3.1 实现Cloneable接口

通过实现Cloneable接口来实现深拷贝是最常见的。

想要实现clone功能,需要实现Cloneable接口,并重写clone方法。

  1. 先创建一个用户类
// 用户的实体类,用作验证
public class User implements Cloneable {
    private String name;
    
    // 每个用户都有一个工作
    private Job job;

    public String getName() {
        return name;
    }

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

    public Job getJob() {
        return job;
    }

    public void setJob(Job job) {
        this.job = job;
    }


    @Override
    public User clone() throws CloneNotSupportedException {
        User user = (User) super.clone();
        // User对象中所有引用类型属性都要执行clone方法
        user.setJob(user.getJob().clone());
        return user;
    }
}
  1. 再创建一个工作类
// 工作的实体类,需要实现Cloneable接口
public class Job implements Cloneable {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    protected Job clone() throws CloneNotSupportedException {
        return (Job) super.clone();
    }
}
  1. 测试浅拷贝
/**
 * @author 一灯架构
 * @apiNote Java深拷贝示例
 **/
public class Demo {

    public static void main(String[] args) throws CloneNotSupportedException {
        // 1. 创建用户对象,{"name":"一灯架构","job":{"content":"开发"}}
        User user1 = new User();
        user1.setName("一灯架构");
        Job job1 = new Job();
        job1.setContent("开发");
        user1.setJob(job1);

        // 2. 拷贝用户对象,name修改为"张三",工作内容修改"测试"
        User user2 = user1.clone();
        user2.setName("张三");
        Job job2 = user2.getJob();
        job2.setContent("测试");
        
        // 3. 输出结果
        System.out.println("user原对象= " + user1);
        System.out.println("user拷贝对象= " + user2);
    }

标签:java,函数,学习,系统,语言,平台,方法,安装,QML,c++,数据
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有