Java的深浅拷贝机制

2023-11-11

Java的深浅拷贝机制

我们先理解一下深浅拷贝的概念

1.浅拷贝:Java在进行对象拷贝的过程中,对于他的成员变量进行拷贝,如果是基本数据类型,就会直接拷贝他的值。如果是引用类型,则会拷贝他的引用地址,而不会拷贝对象本身
2.深拷贝:Java在进行对象拷贝的过程中,对于他的成员变量进行拷贝,如果是基本数据类型,就会直接拷贝他的值。如果是引用类型,不仅会会拷贝他的引用地址,还会拷贝对象本身。

有三种方式实现Java的深浅拷贝机制。

1.用 = 实现(代码示例)

浅拷贝:
		List<Integer> oldObj = new ArrayList<>();
        oldObj.add(1);

        List<Integer> newObj = oldObj;
        newObj.add(2);
        System.out.println("拷贝前:\t" + oldObj);
        System.out.println("拷贝后:\t" + newObj);

执行结果:
在这里插入图片描述
从执行结果可以清晰的看到,拷贝后改变对象后,拷贝前的对象也随之改变。

深拷贝
		List<Integer> oldObj = new ArrayList<>();
        oldObj.add(1);

        List<Integer> newObj = new ArrayList<>(oldObj);
        newObj.add(2);
        System.out.println("拷贝前:\t" + oldObj);
        System.out.println("拷贝后:\t" + newObj);

执行结果
在这里插入图片描述

2.对象实现cloneable接口,重写clone()方法

这种拷贝的方法比较快,方法直接在内存中执行

浅拷贝
public class ShallowCopy {
    public static void main(String[] args) {
        Animal oldAnimal = new Animal("狗",new Dog("二哈"));

        Animal cloneAnimal = null;
        try {
             cloneAnimal = oldAnimal.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        //改变拷贝前的属性值
        oldAnimal.setName("动物");
        oldAnimal.getDog().setName("拉布拉多");
        System.out.println("拷贝前:\t" + oldAnimal);
        System.out.println("拷贝后: \t" + cloneAnimal);
    }
}


@Data
@AllArgsConstructor
@NoArgsConstructor
class Animal implements Cloneable {
    private String name;
    private Dog dog;

    @Override
    protected Animal clone() throws CloneNotSupportedException {
        Animal animal = null;
        animal = (Animal) super.clone();
        animal.setDog(animal.getDog());
        return animal;
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Dog {
    private String name;
}

执行结果
在这里插入图片描述

深拷贝
public class DeepCopy {
    public static void main(String[] args) {
        Animal oldAnimal = new Animal("狗",new Dog("二哈"));

        Animal cloneAnimal = null;
        try {
            cloneAnimal = oldAnimal.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        //改变拷贝前的属性值
        oldAnimal.setName("动物");
        oldAnimal.getDog().setName("拉布拉多");
        System.out.println("拷贝前:\t" + oldAnimal);
        System.out.println("拷贝后: \t" + cloneAnimal);
    }
}


@Data
@AllArgsConstructor
@NoArgsConstructor
class Animal implements Cloneable {
    private String name;
    private Dog dog;

    @Override
    protected Animal clone() throws CloneNotSupportedException {
        Animal animal = null;
        animal = (Animal) super.clone();
        animal.setDog(animal.getDog().clone());
        return animal;
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Dog implements Cloneable{
    private String name;

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

执行结果
在这里插入图片描述

3.序列化拷贝(只能深拷贝)

把对象写入到流中,用的时候再取出来

需要序列化的类一定要实现Serializable接口,不然会报错java.io.NotSerializableException

public class SerialCopy {
    public static void main(String[] args) {
        Animal oldAnimal = new Animal("小狗", new Dog("二哈"));

        Animal cloneAnimal = (Animal)clone(oldAnimal);
        
        oldAnimal.setName("动物");
        oldAnimal.getDog().setName("拉布拉多");

        System.out.println("拷贝前:\t" + oldAnimal);
        System.out.println("拷贝后: \t" + cloneAnimal);
    }

    public static Object clone(Object obj){
        Object cloneObj = null;
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream obs = new ObjectOutputStream(out);
            obs.writeObject(obj);
            obs.close();

            ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(ios);
            cloneObj = ois.readObject();
            ois.close();
        }catch (Exception e){
            throw new RuntimeException();
        }
        return cloneObj;
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Animal implements Serializable{
    private String name;

    private Dog dog;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Dog implements Serializable{
    private String name;
}

执行结果
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java的深浅拷贝机制 的相关文章

  • 使用 REST API 实现属性/字段级安全

    我正在为支持多租户授权模型的 REST API 构建概念验证 该模型不仅控制用户可以访问哪些对象 还控制对象中的字段 此模型的目标是确保租户管理员只能修改其租户并且只能查看允许的对象属性 我有一个正在开发的现有代码库 可在以下位置公开获取
  • @Nullable 和 SonarQube “有条件执行的块应该可达”警告

    包有以下package info java ParametersAreNonnullByDefault package foo import javax annotation ParametersAreNonnullByDefault 类有
  • 如何在没有 Node.JS 的情况下运行 UglifyJS2

    无论如何都要跑UglifyJS2 https github com mishoo UglifyJS2没有node js 假设我想使用 JavaScript 脚本引擎在 JVM 进程中运行它 怎么做 我看到米秀回答你了https github
  • Java 扫描仪问题 (JFrame)

    我正在尝试使用扫描仪来编辑塔防游戏的级别 但是 它不会将级别 图块图像 更新为自定义文件的级别 0 是草 1 是石头 1 是什么都没有 等等 我发现了错误 但如何修复它 我需要添加 更改什么才能消除这个错误 java lang NullPo
  • 如何通过双击图标来执行JAVA程序?

    我写了一个java程序 现在我想在没有 IDE Eclipse 等的情况下打开我的控制台 java 应用程序 只需双击桌面上的可执行版本即可 我已将 java 项目导出为 Runnable JAR 文件 但无法打开 当我尝试使用cmd打开应
  • 可以使用注解进行代码注入吗?

    我意识到这可能是一个已经被提出和回答的问题 但请耐心等待 我想知道是否可以使用注释将代码注入到类编译时 典型的示例是为对象的成员生成 getter 和 setter 这并不完全是我所需要的 但它可以说明基本思想 现在在互联网上我得到的基本答
  • Gradle中的build-by-convention深度解释是什么?

    The 摇篮用户指南 http www gradle org docs current userguide userguide html经常提到 Gradle 是陈述性的和用途按惯例构建 这是什么意思 据我了解 这意味着 例如 在java插
  • 高负载应用程序的数据库可扩展性?

    我见过一些应用程序拥有集群 Web 服务器 例如 10 到 20 个服务器 以具有可扩展性 可以在其中分发 在网络服务器之间加载 但我总是看到所有网络服务器都使用单个数据库 现在考虑任何电子商务或铁路 Web 应用程序 其中有数百万用户在任
  • 我在 Android Studio 中使用哪个版本的 JDK 有关系吗?

    I know I can choose the SDK location in Android Studio s Project Structure 我有两个问题 当我们已经使用Android SDK时 为什么还需要JDK 毕竟我们不是为
  • 有没有办法在@Service上使用@ControllerAdvice

    我有一个项目需求 但我没有任何需求 Controller or RestController但我需要为我的服务层提供一个全局异常处理程序 所以我需要配置 ControllerAdvice on Service 请告诉我是否还有其他方法可以做
  • 在 Retrofit 中的 POST 请求中发送空正文

    我的 api 需要一个空的 json 主体 发出帖子请求时 如何在 Retrofit 和 Jackson 中进行设置 我尝试通过null 和空字符串 以及 但无法让它发挥作用 POST my url Call
  • Java SSO 与 Wildfly 8、Java 1.8.0_45 和 Active Directory

    我对这个主题进行了很多搜索 但找不到解决方案 要求的简短描述 Wildfly 8 2 下 Web 应用程序上的 SSO 在 Active Directory 中验证 Windows 用户的身份 当 SSO 失败时回退到登录表单 在 Wild
  • c3p0 Java 数据库池、故障转移配置

    当数据库关闭时 IP 和端口会自动切换到另一个数据库服务器 我应该如何配置 Web 应用程序的 c3p0 连接池以遵循此数据库故障转移机制 目前 我使用的是 c3p0 但是在上次数据库故障转移中 池连接无法重新建立 请求失败后重新建立 有助
  • egit:设置gitignore忽略所有eclipse项目文件

    我在 github 上有一个项目 我想从中删除所有与 eclipse 相关的文件 并允许克隆它的人使用他们想要的任何 ide 这是该项目 https github com vedi0boy Archipelo https github co
  • Eclipse java 断点 - 目的是什么?

    我正在学习 Android 教程 刚刚进入调试部分 我想知道断点的用途是什么 我还不能告诉 它实际上停止了应用程序 以便我可以确定它运行到该点 或者我可以设置多个断点并将它们用作标记来从断点到断点检查 停止和运行 我的代码 断点是执行停止的
  • 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

    我正在寻找一个适用于在 JDK 1 4 下运行的 Java SE Swing 应用程序的依赖注入框架 有没有我可以使用的推荐 DI 框架 Guice 和其他基于注释的框架已经退出 我不想搞乱像 Retroweaver 这样的东西 另外 Sp
  • 使用 Swift 在 iOS 和 Android 之间共享核心代码

    我想要的是 使用 Swift 在 Android 和 iOS 之间共享非 UI 代码 问题 Android 具有 NDK 支持 允许您使用 Java 本机接口 JNI 运行 C 和 C 代码 不是 Objective C 我是一名Java程
  • Java 需要一个 FileSet 包/类

    任何人都可以建议 Java 中的 FileSet 包 类吗 我所说的 FileSet 是指文件和目录的集合以及正则表达式支持的包含和排除规则 类似于 Apache Ant 谢谢 Apache 公共 IO文件工具 http commons a
  • java银行程序帐户ID不上去?

    每次创建银行帐户时 帐户 ID 都应增加 1 但每次我尝试提取 Id 时 我只会得到帐户 ID 为 0 任何建议 因为我完全按照我学习的书中的方式进行操作而且它仍然没有更新 帐户构造函数 public class BankAccount p
  • 将菜单添加到空活动

    我在 Android Studio 中制作了一个 Android 应用程序 并想在其上创建一个选项菜单 我将其创建为一个空活动 现在意识到我最好创建一个空白活动来获取选项菜单 无论如何 是否可以在空活动中创建选项菜单 如果有人能给我指出一个

随机推荐

  • Unity中的Debug类调试使用

    UnityEngine Debug Class containing methods to ease debugging while developing a game 该类中包含了一些便于游戏开发时的调试方法 Class Variable
  • The content of element type “configuration“ must match “(properties?,settings?,typeAliases?,typeHand

    注意 每个标签必须按顺序写
  • 有源滤波器治理谐波好在哪

    减小谐波影响应对谐波源本身或在附近采取适当的措施 通常情况下 采用加装滤波器的方式治理谐波 滤波器一般分为无源滤波器和有源滤波器 下面领步 北京 根据多年的实践经验给出一个具体的解决方案 在有谐波问题是 什么样的选择才是最好的 谐波的危害
  • React---使用componentDidUpdate钩子函数判断路由地址是否发生变化

    在组件更新 例如组件的路由更新 后会执行componentDidUpdate钩子函数 componentDidUpdate方法会传入两个参数 prevProps prevState prevProps prevState可以拿到组件更新前的
  • Web3 入门手册:从认知到实践

    如果你也喜欢 Web3 希望在这做些有趣的 有意义的事情 那么我希望这篇文章可以帮助到你 送给想要进入 Web3 或者刚刚进入 Web3 的小伙伴 但是考虑到两点原因 我还是打算把这件事推迟一些时日 一是在各大媒体都鼓吹 All In We
  • 如何将pdf转换成txt?悄悄告诉你3个好用的转换方法

    pdf和txt文档都是我们经常会使用到的文档格式 这两种文档各有各的特点 pdf文档适合用于展示 而txt文档适合用于整理各种文字信息 在面对不同的情况时我们就要使用不同的文档 就比如将纯文字的资料进行搜集的时候 利用txt文档会更方便 而
  • 如何在vue中引入字体

    一 为什么要引入字体 在前端开发中 选用合适的字体往往会极大地提升网站的视觉体验 然而 网页中默认字体的种类和风格有限 且在不同的设备 浏览器上渲染效果不尽相同 因此 很多开发者会选择自定义字体来提升用户体验 二 如何引入字体 1 搜索下载
  • 2020华为杯数学建模总结

    2020研究生数学建模竞赛总结 题目 2020年中国研究生数学建模竞赛B题 降低汽油精制过程中的辛烷值损失模型 一 背景 汽油是小型车辆的主要燃料 汽油燃烧产生的尾气排放对大气环境有重要影响 为此 世界各国都制定了日益严格的汽油质量标准 见
  • linux 套接字文件类型,Linux下的文件类型

    Linux下的文件类型 1 开头 表示普通文件 2 d开头 表示目录文件 3 b开头 表示块设备 4 c开头 表示是字符设备 5 I开头 表示符号链接文件 6 p开头 表示管道文件pipe 7 s开头 表示套接字文件socket root
  • 浅谈BERT/Transformer模型的压缩与优化加速

    作者 姚益武 单位 阿里巴巴集团 研究方向 AI算法与工程架构 前言 BERT Transformer 结构及其变体 已成为自然语言处理 NLP 语音识别 ASR 等领域的主流序列建模结构 并且 相比于卷积操作的局部特征提取能力 以及平移不
  • 【Python】ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any

    一 问题描述 在使用Python的判断语句的时候 data2 data2 Month 11 and data2 Day 11 我的本意是想找出11月11日的数据 运用上面的代码 却得到了报错 报错信息 ValueError The trut
  • [QT编程系列-38]:数据存储 - SQLite数据库存储与操作

    目录 1 SQLite数据库概述 1 1 简介 1 2 SQLite不支持网络连接 1 3 SQLite不需要安装MySQL Server数据库 1 4 SQLite性能 1 5 SQLite支持的数据条目 2 SQLite操作示例 3 Q
  • 找不到插件 ‘org.springframework.boot:spring-boot-maven-plugin:‘问题

    出现pom文件找不到插件 org springframework boot spring boot maven plugin 问题 可能是因为版本没有绑定好 去一级父类依赖找对应的插件版本 在pom文件中加上 把父类的version加到po
  • 1小时学会CSS-下

    今天给大家分享的内容包含CSS 盒子模型 CSS 标准布局 CSS 浮动布局 并以案列进行详细说明 一 CSS 盒子模型 CSS 将所有元素都当成盒子 CSS布局其实就是如何堆放盒子 组成 content 内容 gt padding 内边距
  • 【c语言】小程序游戏——飞机游戏(二)

    在接下来 我们需要对飞机添加一些属性 1 利用键盘控制飞机的移动 2 按空格键可以发射激光 NO 1 利用键盘控制飞机的移动 首先我们需要了解的是 如果想要通过按键来控制飞机的移动 那么我们具体要怎么控制呢
  • Verilog(4)系统任务monitor,time,stop,random等,编译预处理语句

    调试用系统任务和常用编译预处理语句 用于调试和差错的系统任务 以及编写模块时的预处理语句 系统任务 monitor 提供了监控和输出参数列表中表达式或变量值的功能 参数列表中输出控制格式字符串和输出表列的规则和 d i s p l a
  • java基础之replace,replaceAll

    走在乡间的小路上 回首过往 以下代码结果都是显示在Console框中 所以 n会被解析成换行 n只显示 n 所以看到结果换行其实是输出了 n 看到输出 n 其实输出的是 n replace和replaceAll是编程中经常用到的替换函数 成
  • 求出1~N范围中所有的素数

    判断是否为素数 public static boolean isPrime int n int sqrt int Math sqrt n int i for i 2 i lt sqrt i if n i 0 break if i gt sq
  • 小程序瀑布流布局

    list wxml列表
  • Java的深浅拷贝机制

    Java的深浅拷贝机制 我们先理解一下深浅拷贝的概念 1 浅拷贝 Java在进行对象拷贝的过程中 对于他的成员变量进行拷贝 如果是基本数据类型 就会直接拷贝他的值 如果是引用类型 则会拷贝他的引用地址 而不会拷贝对象本身 2 深拷贝 Jav