举例说明深拷贝和浅拷贝

news/2024/7/18 22:42:47 标签: java, 开发语言

概述

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

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

java">int age = 18;
Student stu1 = new Student();

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

拷贝

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

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

举个通俗的例子

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

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

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

图片来源:JavaGuide 

实例代码

浅拷贝

java">/**
* 地址类
*
*/

@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();
        }
    }
}
java">/**
* 测试
*/ 
Person person1 = new Person();
Person clone = person1.clone();
System.out.println(person1.getAddress() == clone.getAddress());

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

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

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

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

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


http://www.niftyadmin.cn/n/5544433.html

相关文章

PageHelper分页查询遇到的小问题

如果我们是这样子直接查询 pagehelper会拼接导我们的sql语句之后 这样子我们搜索出来的list&#xff0c;就是里面参杂了PageHelper的东西 所以我们可以直接转成我们的Page类型 但是如果我们搜索出来的是List<Blog>&#xff0c;我有些信息不想返回给前端&#xff0c;所以…

好用的IP反查接口(2)

IP-地理信息查询接口-本地化 参考&#xff1a; 通过Ip查询对应地址,Ip2location全球IP地址网段-CSDN博客 因为在线接口有限制&#xff08;毕竟别人提供服务&#xff0c;服务器&#xff0c;数据维护&#xff0c;域名啥的都要费用&#xff09;&#xff0c; 所以本地化服务的需…

LeetCode 744, 49, 207

目录 744. 寻找比目标字母大的最小字母题目链接标签思路代码 49. 字母异位词分组题目链接标签思路代码 207. 课程表题目链接标签思路代码 744. 寻找比目标字母大的最小字母 题目链接 744. 寻找比目标字母大的最小字母 标签 数组 二分查找 思路 本题比 基础二分查找 难的一…

markdown文件转pdf

步骤&#xff1a;md转html转pdf pom引入 <!--markdown 转pdf--><dependency><groupId>com.vladsch.flexmark</groupId><artifactId>flexmark-all</artifactId><version>0.64.8</version></dependency><dependency&g…

快速上手:前后端分离开发(Vue+Element+Spring Boot+MyBatis+MySQL)

文章目录 前言项目简介环境准备第一步&#xff1a;初始化前端项目登录页面任务管理页面 第二步&#xff1a;初始化后端项目数据库配置数据库表结构实体类和Mapper服务层和控制器 第三步&#xff1a;连接前后端总结 &#x1f389;欢迎来到架构设计专栏~探索Java中的静态变量与实…

唯迈医疗随经贸团赴埃塞俄比亚探讨合作共促发展

近日&#xff0c;唯迈医疗参加了由北京市贸促会组织的赴埃塞俄比亚经贸代表团。埃塞俄比亚在非洲具有重要战略地位&#xff0c;也是非洲的门户&#xff0c;资源丰富、人口众多且年轻化程度高、经济增长速度快。经贸团一行在埃塞俄比亚拜会了中国驻埃塞俄比亚使馆&#xff0c;埃…

SpringBoot源码阅读(1)——环境搭建

SpringBoot官网 官网 https://spring.io/projects/spring-boot 代码仓库 github&#xff1a;https://github.com/spring-projects/spring-boot gitee: https://gitee.com/mirrors/spring-boot 下载代码 git clone https://gitee.com/mirrors/spring-boot.git下载的代码中有些…

手机数据恢复:如何在没有root的情况下恢复Android数据?

您是否不小心从Android设备中删除了重要数据&#xff1f;您是否担心如何取回您的照片、视频和文档&#xff1f;有时&#xff0c;我们不小心删除了重要数据&#xff0c;并使用Android root方法取回文件。许多用户不喜欢root他们的Android设备&#xff0c;因为这是一种复杂的方法…