Java深拷贝和浅拷贝区别?

大家好,我是锋哥。今天分享关于【Java深拷贝和浅拷贝区别?】面试题。希望对大家有帮助;

Java深拷贝和浅拷贝区别?

1000道 互联网大厂Java工程师 精选面试题-Java资源分享网

在Java中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种常用的对象复制方式。它们的区别主要体现在复制过程中,引用类型字段的处理方式不同。下面详细介绍它们的区别:

1. 浅拷贝(Shallow Copy)

  • 定义:浅拷贝指的是创建一个新的对象,但该对象中的引用类型字段(例如对象类型的成员变量)依然指向原对象的内存地址。也就是说,拷贝的是对象的引用,而不是对象所引用的内容。

  • 特征

    • 如果一个对象包含引用类型字段,那么浅拷贝会复制这些引用字段的地址,而不是复制它们所指向的对象。
    • 对于基本类型字段,浅拷贝会直接复制值。
    • 因此,原对象和拷贝对象中的引用类型字段会指向同一块内存,若修改其中一个对象的引用字段,可能会影响到另一个对象。
  • 实现方式

    • 使用 Object.clone() 方法或者手动复制字段。
  • 示例

    class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}
    }class ShallowCopyExample {public static void main(String[] args) {Person person1 = new Person("John", 25);Person person2 = person1; // 浅拷贝,只是复制引用// 修改 person2person2.name = "Jane";System.out.println(person1.name); // 输出: JaneSystem.out.println(person2.name); // 输出: Jane}
    }
    

    在上面的例子中,person1person2 指向同一个 Person 对象。因此,修改 person2 的字段会影响到 person1

2. 深拷贝(Deep Copy)

  • 定义:深拷贝指的是创建一个新的对象,并且递归地复制对象所引用的所有对象。也就是说,不仅复制对象本身,还复制对象中引用的所有对象,最终得到的拷贝是完全独立的,修改原对象或拷贝对象都不会互相影响。

  • 特征

    • 对于基本类型字段,深拷贝会直接复制其值。
    • 对于引用类型字段,深拷贝会创建新的对象并复制引用类型字段所指向的内容,从而保证原对象和拷贝对象完全独立。
    • 适用于复杂对象或者多级嵌套对象的复制,确保数据的完全隔离。
  • 实现方式

    • 通常需要手动实现深拷贝方法,或者通过序列化(序列化 + 反序列化)来实现深拷贝。
    • 使用 Object.clone() 方法时,如果对象内含有引用类型字段,需要覆盖 clone() 方法来实现深拷贝。
  • 示例

    class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}// 深拷贝public Person deepCopy() {return new Person(this.name, this.age);}
    }class DeepCopyExample {public static void main(String[] args) {Person person1 = new Person("John", 25);Person person2 = person1.deepCopy(); // 深拷贝,创建一个新对象// 修改 person2person2.name = "Jane";System.out.println(person1.name); // 输出: JohnSystem.out.println(person2.name); // 输出: Jane}
    }
    

    在这个例子中,person2 是通过 deepCopy() 方法创建的深拷贝对象。修改 person2 的字段不会影响 person1,因为它们是完全独立的对象。

3. 总结对比

区别浅拷贝深拷贝
复制对象的方式只复制对象本身,引用类型字段仍指向原对象的内存复制对象本身,并递归地复制引用类型字段指向的对象
修改影响修改拷贝对象的引用类型字段会影响原对象修改拷贝对象不会影响原对象
性能通常较快,因为只复制对象引用性能较差,因为需要复制整个对象图
实现方式可以使用 clone() 或手动复制字段通常需要手动实现,或者通过序列化技术

4. 注意事项

  • 如果对象中的字段类型是基本类型(如 intchar 等),浅拷贝和深拷贝效果相同,因为这些字段直接存储值而不是引用。

  • 对于包含嵌套对象的复杂对象,深拷贝会更加重要,因为浅拷贝无法有效防止对象之间的共享引用导致的潜在问题。

  • 在 Java 中,如果想要实现深拷贝,有时可以借助 Java 的序列化机制(将对象序列化为字节流,再反序列化为一个新的对象)来完成,特别是对于复杂对象的深拷贝。

    例如:

    import java.io.*;public class DeepCopyExample {public static Object deepCopy(Object obj) {try {// 写入当前对象的字节流ByteArrayOutputStream byteStream = new ByteArrayOutputStream();ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);objectStream.writeObject(obj);objectStream.flush();// 通过字节流读取并返回新的对象ByteArrayInputStream inputByteStream = new ByteArrayInputStream(byteStream.toByteArray());ObjectInputStream objectInputStream = new ObjectInputStream(inputByteStream);return objectInputStream.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();return null;}}public static void main(String[] args) {// 使用序列化进行深拷贝Person person1 = new Person("John", 25);Person person2 = (Person) deepCopy(person1); // 深拷贝person2.name = "Jane";  // 修改 person2System.out.println(person1.name); // 输出: JohnSystem.out.println(person2.name); // 输出: Jane}
    }
    

通过这种方法,能够确保对象被完全深拷贝。

希望这些解释对你理解 Java 中的深拷贝和浅拷贝有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/64429.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React 第十七节 useMemo用法详解

概述 useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果; 大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性…

全国数据资源入表年度发展报告(2024)(附下载)

近日,在“数据要素暨第二届数据资产价值大会”上,青岛、潍坊、湖州、广西等地的数据资产登记评价中心,联合发布了《全国数据资源入表年度发展报告(2024)》。 报告内容包括全国数据资源入表的总体发展概述、政策指引、…

如何设置浏览器不缓存网页

设置浏览器不缓存网页可以通过多种方法实现,以下是一些常见的策略: HTTP响应头控制: Cache-Control:这是最常用的HTTP头之一,用于控制响应的缓存行为。例如: Cache-Control: no-cache, no-store, must-r…

ZZNUOJ_1341:简单密码破解(C/C++/Java)

题目描述 密码是我们生活中非常重要的东东,我们的那么一点不能说的秘密就全靠它了。哇哈哈. 接下来渊子要在密码之上再加一套密码,虽然简单但也安全。 假设渊子原来一个BBS上的密码为zvbo941987,为了方便记忆,他通过一种算法把这个密码变换成YUANzi1987,这个密码是他的…

React状态管理常见面试题目(一)

1. Redux 如何实现多个组件之间的通信?多个组件使用相同状态时如何进行管理? Redux 实现组件通信 Redux 是一个集中式的状态管理工具,通过共享一个全局 store 来实现多个组件之间的通信。 通信机制: 所有状态保存在 Redux 的全局 store 中。使用 ma…

第十六周做题总结_数据结构_AVL与哈希查找

id:157 A. DS二叉平衡树构建 题目描述 在初始为空的平衡二叉树中依次插入n个结点,请输出最终的平衡二叉树。 要求实现平衡二叉树,不可以使用各类库函数。 AVL代码参考模板: #include <iostream> using namespace std;#define LH 1 // 左高 #define EH 0 // 等高 …

Rust操作符和符号全解析

Rust是一种系统编程语言&#xff0c;它的语法丰富而严谨&#xff0c;包括了一系列的操作符和符号。这些操作符和符号是构建Rust程序的基本元素&#xff0c;它们用于执行各种操作&#xff0c;如算术运算、逻辑比较、类型约束等。本文将详细介绍Rust中的操作符和符号&#xff0c;…

【Mybatis】MyBatis 探秘:#{} 与 ${} 参传差异解码,数据库连接池筑牢数据交互根基

前言 &#x1f31f;&#x1f31f;本期讲解关于Spring IOC&DI的详细介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么…

解锁 draw.io 流程图制作工具的强大功能与应用(1/2)

一、draw.io 简介 &#xff08;一&#xff09;基本概述 draw.io 是一款由 JGraph 公司开发的基于网页的在线图表绘制工具。它最大的优势之一就是无需进行繁琐的下载和安装步骤&#xff0c;只要打开浏览器&#xff0c;访问其官网&#xff0c;就能立即开始使用。无论是在 Window…

ai论文写作免费平台:五款AI论文写作辅助工具的对比与分析

随着人工智能技术的飞速发展&#xff0c;越来越多的AI工具应运而生&#xff0c;为学术写作带来了前所未有的便利。本文将对千笔AI论文、笔灵AI论文、Smodin、以及Notion AI等五款AI论文写作辅助工具进行全面的对比与分析&#xff0c;以帮助用户更好地了解这些工具的优势和特点&…

三、基于langchain使用Qwen搭建金融RAG问答机器人--检索增强生成

经过前面2节数据准备后&#xff0c;现在来构建检索 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingFaceEmbeddings import os# 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name"m3e-base")#…

数据仓库工具箱—读书笔记02(Kimball维度建模技术概述02、事实表技术基础)

Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考&#xff0c;摘录一些书中关于维度建模比较重要的思想与大家分享&#x1f923;&#x1f923;&#x1f923; 第二章前言部分作者提到&#xff1a;技术的介绍应该通过涵盖各种行业的熟悉的用例展开&#xff08;赞同…

fabric.js

目录 一、在canvas上画简单的图形 二、在canvas上用路径(Path)画不规则图形 三、在canvas上插入图片并设置旋转属性(angle) 四、让元素动起来(animate) 五、图像过滤器(filters)让图片多姿多彩 六、颜色模式(Color)和相互转换(toRgb、toHex) 七、对图形的渐变填充(Gradi…

Liinux下VMware Workstation Pro的安装,建议安装最新版本17.61

建议安装最新版本17.61&#xff0c;否则可能有兼容性问题 下载VMware Workstation安装软件 从官网网站下载 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro 选择所需版本 现在最新版本是17.61&#xff0c;否则可能有兼容性问题…

压力测试Jmeter简介

前提条件&#xff1a;要安装JDK 若不需要了解&#xff0c;请直接定位到左侧目录的安装环节。 1.引言 在现代软件开发中&#xff0c;性能和稳定性是衡量系统质量的重要指标。为了确保应用程序在高负载情况下仍能正常运行&#xff0c;压力测试变得尤为重要。Apache JMeter 是一…

Android-ImagesPickers 拍照崩溃优化

Android-ImagesPickers 作为老牌图片选择器&#xff0c;帮助了很多牛马宝宝&#xff0c;刚好最近用到了多相册选择以及拍照&#xff0c;可能是高版本机型问题&#xff0c;导致拍照后就闪退 原作者文章以及git Android实用视图动画及工具系列之九&#xff1a;漂亮的图片选择器…

前端的知识(部分)

11 前端的编写步骤 第一步:在HTML的页面中声明方法 第二步:在<script>中定义一个函数,其中声明一个data来为需要的数据 赋值一个初始值 第三步:编写这个方法实现对应的功能

LSTM详解

1. LSTM设计 LSTM(长短期记忆网络)详解 长短期记忆网络(LSTM, Long Short-Term Memory) 是一种特殊的循环神经网络(RNN),特别适合处理和预测序列数据中的长时间依赖关系。LSTM 通过引入“门机制”(如输入门、遗忘门、输出门)来解决标准 RNN 在长时间序列任务中梯度消…

我在广州学 Mysql 系列之 数据类型和运算符详解

ℹ️大家好&#xff0c;我是&#x1f606;练小杰&#xff0c;今天主要学习 Mysql的数据类型以及运算符操作~~ 上周五学习了“Mysql 系列之 数据“表”的基本操作”~ 想要了解更多&#x1f236;️MYSQL 数据库的命令行总结&#xff01;&#xff01;&#xff01; “我是你的敌人,…

SQL Server 表值函数使用场景有哪些

表值函数&#xff08;Table-Valued Functions, TVFs&#xff09;在 SQL Server 中非常有用&#xff0c;适用于多种场景。以下是常见的使用场景&#xff1a; 1. 数据提取和转换 • 数据过滤&#xff1a;根据特定条件从表中提取数据。 • 数据聚合&#xff1a;对数据进行聚…