死磕Java面试系列:深拷贝与浅拷贝的实现原理
2022/11/8 1:24:07
本文主要是介绍死磕Java面试系列:深拷贝与浅拷贝的实现原理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
深拷贝与浅拷贝的问题,也是面试中的常客。虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝。其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入剖析一下深拷贝与浅拷贝的实现原理,并手把手教你怎么优雅的实现深拷贝。
1. 什么是深拷贝与浅拷贝
浅拷贝: 只拷贝栈内存中的数据,不拷贝堆内存中数据。
深拷贝: 既拷贝栈内存中的数据,又拷贝堆内存中的数据。
2. 浅拷贝的实现原理
由于浅拷贝只拷贝了栈内存中数据,栈内存中存储的都是基本数据类型,堆内存中存储了数组、引用数据类型等。
使用代码验证一下:
想要实现clone功能,需要实现 Cloneable
接口,并重写 clone
方法。
- 先创建一个用户类
// 用户的实体类,用作验证 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; } }
- 再创建一个工作类
// 工作的实体类,并没有实现Cloneable接口 public class Job { private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
- 测试浅拷贝
/** * @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
方法。
- 先创建一个用户类
// 用户的实体类,用作验证 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; } }
- 再创建一个工作类
// 工作的实体类,需要实现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(); } }
- 测试浅拷贝
/** * @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面试系列:深拷贝与浅拷贝的实现原理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22Java创业学习:初学者的全面指南
- 2024-11-22JAVA创业学习:零基础入门到实战应用教程
- 2024-11-22Java创业学习:从零开始的Java编程入门教程
- 2024-11-22Java对接阿里云智能语音服务学习教程
- 2024-11-22JAVA对接阿里云智能语音服务学习教程
- 2024-11-22Java对接阿里云智能语音服务学习教程
- 2024-11-22Java副业学习:零基础入门到实战项目
- 2024-11-22Java副业学习:零基础入门指南
- 2024-11-22Java微服务学习:入门与实践指南
- 2024-11-22JAVA项目部署学习:从入门到实践