当前位置: 首页 > news >正文

Java 到底是值传递还是引用传递?

C 语言是很多变成语言的母胎,包括 Java。对于 C 语言来说,所有的方法参数都是通过 “值” 传递的,也就是说,传递给被调用方法的参数值存放在临时变量中,而不是存放在原来的变量中。这就意味着,被调用的方法不能修改调用方法中变量的值,只能修改其私有变量的临时副本的值。

Java 继承了 C 语言的这一个特性,所以 Java 是按照值来传递的。

接下来我们就要搞清楚:到底什么是值传递,什么是引用传递?

  • 当一个参数按照值的方式在两个方法之间传递时,调用者和被调用者其实是用两个不同的变量——被调用者中的变量(原始值)是调用者中变量的一份拷贝,对它们当中的任何一个变量修改都不会影响到另外一个变量。
  • 当一个参数按照引用传递的方式在两个方法之间传递时,调用者和被调用者其实用的是同一个变量,当该变量被修改时,双方都是可见的。

我们之所以搞不清楚 Java 到底是值传递还是引用传递,主要是因为 Java 中的两类数据类型的叫法容易引发误会。比如:int 是基本数据类型,说它是值传递就比较容易理解;但是对于引用类型,比如说 String,说它是值传递的时候,就很容易混淆。

看一下基本数据类型和引用数据类型之间的差别:

  • 定义一个基本数据类型和引用类型变量

    /*** @author qiaohaojie* @date 2023/3/17  17:46*/
    public class TransferTest {public static void main(String[] args) {// 基本数据类型int age = 18;// 引用数据类型String name = "青花椒";System.out.println("age" + age + ",name=" + name); // age18,name=青花椒
    }
    

    age 是基本数据类型,值就保存在变量中;name 是引用数据类型,变量中保存的是对象的地址,所以变量 name 称为对象的引用,存放在栈中,而对象存放在堆中。

    这里说的对和栈,指的是内存中的一块区域,和数据结构中的堆和栈不同。栈是由编译器自动分配释放的,所以适合存放编译期就确定生命周期的数据;而堆中存放的数据,编译器是不需要知道生命周期的,创建后的回收工作由垃圾收集器来完成。

    在这里插入图片描述

  • 用 = 赋值运算符改变值

    /*** Java值传递测试** @author qiaohaojie* @date 2023/3/18  16:46*/
    public class TransferTest2 {public static void main(String[] args) {// 基本数据类型int age = 18;// 引用数据类型String name = "青花椒";System.out.println("age" + age + ",name=" + name); // age18,name=青花椒age = 23;name = "青花椒2";System.out.println("age" + age + ",name=" + name); // age23,name=青花椒2}
    }

    对于基本数据类型 age,赋值运算符会直接改变变量的值,原来的值被覆盖。

    对于引用类型 name,赋值运算符会改变对象引用中保存的地址,原来的地址被覆盖,但是原来的对象不会被覆盖。
    在这里插入图片描述

接下来我们分析一下基本数据类型和引用数据类型的参数传递

  • 基本数据类型参数传递

    Java 有 8 种基本数据类型,分别是 byte、short、int、long、float、double、char 和 boolean,就拿 int 类型来举例子:

    /*** @author qiaohaojie* @date 2023/3/17  17:46*/
    public class TransferTest {public static void main(String[] args) {// 基本数据类型int age = 18;modified(age);System.out.println(age); // 18}private static void modified(int age1) {age1 = 30;}
    }
    

    程序执行的步骤是这样的:

    1. main() 方法中的 age 为基本数据类型,所以它的值 18 直接存储在变量中;

    2. 调用 modified() 方法的时候,会把 age 的值 18 复制给形参 age1;

    3. modified() 方法中,对 age1 进行了修改;

    4. 回到 main() 方法中,age 的值仍然是 18,并没有发生改变。

      age 的值并没有按照我们想要的结果改变,是因为对 age1 的值进行了修改后,并没有返回。这就需要返回后重新对 age 进行赋值:

    /*** @author qiaohaojie* @date 2023/3/17  17:46*/
    public class TransferTest {public static void main(String[] args) {// 基本数据类型int age = 18;modified(age);System.out.println(age); // 18age = modified2(18);System.out.println(age); // 30}private static void modified(int age1) {age1 = 30;}private static int modified2(int age2) {age2 = 30;return age2;}
    }
    
  • 引用数据类型参数传递

    引用数据类型以 String 为例:

    /*** @author qiaohaojie* @date 2023/3/17  17:46*/
    public class TransferTest {public static void main(String[] args) {	// 引用数据类型String name = "青花椒";modified(name);System.out.println(name); // 青花椒System.out.println(Integer.toHexString(System.identityHashCode(name))); // 38291283}private static void modified(String name1) {name1 = "青花椒2";}
    }
    

    在调用 modified() 方法的时候,形参 name1 复制了 name 的地址,指向的是堆中的 “青花椒” 位置:

    在这里插入图片描述

    当 modified() 方法调用结束后,改变了形参 name1 的地址,但是 main() 方法中 name 并没有发生改变:
    在这里插入图片描述

总结:

  • Java 中的参数传递是按照值传递的。
  • 如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
  • 如果参数是引用类型,传递的是引用的对象在堆中地址的拷贝。

相关文章:

Java 到底是值传递还是引用传递?

C 语言是很多变成语言的母胎,包括 Java。对于 C 语言来说,所有的方法参数都是通过 “值” 传递的,也就是说,传递给被调用方法的参数值存放在临时变量中,而不是存放在原来的变量中。这就意味着,被调用的方法…...

Apollo 配置变更原理

我们经常用到apollo的两个特性:1.动态更新配置:apollo可以动态更新Value的值,也可以修改environment的值。2.实时监听配置:实现apollo的监听器ConfigChangeListener,通过onChange方法来实时监听配置变化。你知道apollo…...

聊聊「订单」业务的设计与实现

订单,业务的核心模块; 一、背景简介 订单业务一直都是系统研发中的核心模块,订单的产生过程,与系统中的很多模块都会高度关联,比如账户体系、支付中心、运营管理等,即便单看订单本身,也足够的复…...

血细胞智能检测与计数软件(Python+YOLOv5深度学习模型+清新界面版)

摘要:血细胞智能检测与计数软件应用深度学习技术智能检测血细胞图像中红细胞、镰状细胞等不同形态细胞并可视化计数,以辅助医学细胞检测。本文详细介绍血细胞智能检测与计数软件,在介绍算法原理的同时,给出Python的实现代码以及Py…...

高速PCB设计指南(十五)

掌握IC封装的特性以达到最佳EMI抑制性能 将去耦电容直接放在IC封装内可以有效控制EMI并提高信号的完整性,本文从IC内部封装入手,分析EMI的来源、IC封装在EMI控制中的作用,进而提出11个有效控制EMI的设计规则,包括封装选择、引脚结…...

GPT-4:我不是来抢你饭碗的,我是来抢你锅的

目录 一、GPT-4,可媲美人类 二、它和ChatGPT 有何差别? 01、处理多达2.5万字的长篇内容 02、分析图像的能力,并具有「幽默感」 03、生成网页 三、题外话 四、小结 GPT-4的闪亮登场,似乎再次惊艳了所有人。 看了GPT-4官方的…...

Scala环境安装【傻瓜式教程】

文章目录安装scala环境依赖Java环境安装下载sacla的sdk包安装Scala2.12检查安装是否成功idea配置idea安装scala插件项目配置新建maven项目添加框架支持选择scala创建测试类安装scala环境依赖 Java环境安装 sacla环境安装之前需要先确认Java jdk安装完成 java具体安装步骤略&…...

js实现一个简单的扫雷

目录先看下最终的效果:首先来分析一个扫雷游戏具有哪些功能分析完成后我们就开始一步步的实现1. 相关html和css2. 我们使用类来完成相应功能3. 之后我们则是要定义一个地图4. 对地图进行渲染5. 对开始按钮添加点击事件6. 现在我们可以实现鼠标左击扫雷的功能7. 给单…...

禁用非必需插件,让 IDEA 飞起

文章首发于个人博客,欢迎访问关注:https://www.lin2j.tech IDEA 为我们提供了众多的插件,但是这些插件并不都是必须的。如果电脑的性能不够强,反而会带来一些不必要的资源消耗。 因此这里整理了一些不常用的插件,可以…...

解决win10任何程序打开链接仍然为老旧IE的顽固问题[修改默认浏览器]

文章目录一、问题与修改原因1、着手修改吧2、弯路上探索3、发现祸根二、后话文章原出处: https://blog.csdn.net/haigear/article/details/129344503一、问题与修改原因 我们发现,很多程序默认的网页打开浏览器都是IE,这个很是郁闷&#xff…...

计算机网络体系结构——“计算机网络”

各位CSDN的uu们你们好呀,今天小雅兰来学习一个全新的知识点,就是计算机网络啦,下面,开始虚心学习。 计算机网络的概念 计算机网络的功能 计算机网络的组成 计算机网络的分类 标准化工作 计算机网络的性能 计算机网络的概念 …...

基于微信小程序的校园二手交易平台小程序

文末联系获取源码 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器…...

Linux lvm管理讲解及命令

♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放&#xff0…...

GPT-4,终于来了!

就在昨天凌晨,OpenAI发布了多模态预训练大模型GPT-4。 这不昨天一觉醒来,GPT-4都快刷屏了,不管是在朋友圈还是网络上都看到了很多信息和文章。 GPT是Generative Pre-trained Transformer的缩写,也即生成型预训练变换模型的意思。…...

面部表情识别3:Android实现表情识别(含源码,可实时检测)

面部表情识别3:Android实现表情识别(含源码,可实时检测) 目录 面部表情识别3:Android实现表情识别(含源码,可实时检测) 1.面部表情识别方法 2.人脸检测方法 3.面部表情识别模型训练 4.面部表情识别模型Android部署 &#x…...

【IT女神勋章挑战赛名单公布】:看看谁获奖啦!

致敬女性开发者,为那些IT女神而战!「IT女神勋章挑战赛」已落下帷幕,博主们的比拼结果也已新鲜出炉,快来看看此次征文中,有哪些精彩文章不容错过!活动官网:https://activity.csdn.net/creatActiv…...

ThreadPool线程池源码解析

ThreadPool线程池源码解析 文章目录前言一、基本使用二、执行流程三、源码分析ThreadPoolExecutor 中重要属性ThreadPoolExecutor 内部类Workerexecute()方法addWorker(command, true)方法runWorker(worker )方法getTask()方法shutdown和shutdownNow四、…...

Python中 5个非常有用的单行代码

Python中 5个非常有用的单行代码1. 什么是单行代码?2. 了解和使用单行代码的好处3. 5个单行代码示例参考作为开发人员,你想提高生产力吗?掌握这 5 个 Python 一行代码,你就能写出简洁的代码。 这篇博客将介绍5个非常有用的初学者可…...

蓝牙模块各种工作模式

摘要:本文主要归纳总结蓝牙模块的不同工作模式,通过蓝牙模块不同的工作模式了解其扮演不同角色时工作的一个基本原理,为更深入的研究蓝牙模块底层的工作机制和技术方案进行铺垫。 1、主设备工作模式 主设备是能够搜索别人并主动建立连接的一…...

修剪灌木[蓝桥杯2022初赛]

题目描述 爱丽丝要完成一项修剪灌木的工作。 有 N 棵灌木整齐的从左到右排成一排。 爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为 0 厘米。 爱丽丝修剪灌木的顺序是从最左侧的灌木开始,每天向右修剪一棵灌木。 当修剪了最右侧的灌木后,…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...