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

java 的参数传递

一、疑惑引入

首先,我们从一个例子来引出这个问题:

public static void main(String[] args) throws IOException {List<String> mockList = Lists.newArrayList("a", "b");System.out.println("1: " + mockList);List<String> result = change(mockList);System.out.println("3: " + mockList);System.out.println("4: " + result);
}
public static List<String> change(List<String> input){List<String> result = input.stream().sorted(Comparator.comparing(String::valueOf).reversed()).collect(Collectors.toList());System.out.println("2: " + result);return result;
}

请问,1,2,3,4 处分别输出的应该是什么?
答案是:

1: [a, b]
2: [b, a]
3: [a, b]
4: [b, a]

看到这里,同学对 1,2,4 的结果肯定是不会有疑问,可能会有一部分同学会对 3 的输出有些疑问,change方法不是对序列进行了倒排,为啥3 处mockList 的序列没变,如果有这个疑问的同学,那么你有必要要认真看下本文;
常见大家理解的误区可能有以下几点:

  1. 值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。
  2. Java是引用传递。
  3. 传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递

二、概念理解

首先,要理解这个问题,我们先来了解下几个概念

2.1、形参、实参

在编程中,参数(parameters)是指在函数定义中声明的占位符,用于接收传递给函数的值。

  • 形参(formal parameters)是函数定义中使用的参数名称,它们在函数定义时被声明。
  • 实参(actual parameters)是在函数调用时传递给函数的实际值。
    具体来说,形参是函数定义时使用的变量名,用于表示函数内部使用的值。它们在函数定义的括号内列出,并且可以有一个或多个。形参是函数内部的局部变量,只在函数内部可见和使用。
    下面是一个示例函数定义,其中x和y是形参:
def add_numbers(x, y):sum = x + yreturn sum

在这个例子中,add_numbers函数接受两个形参x和y,并返回它们的和。
实参是在函数调用时传递给函数的具体值。它们是实际用于执行函数操作的值。在函数调用时,实参被传递给函数,填充形参,并在函数体内使用。
下面是调用上述函数并传递实参的示例:

result = add_numbers(3, 5)

在这个例子中,3和5是传递给add_numbers函数的实参。函数将使用这些实参来执行计算并返回结果。

以上解释来自chatGpt

显然可能有点啰嗦,喜欢直接一点的同学直接看红框
[图片]

2.2、值传递和引用传递

值传递(pass by value)是指在函数调用时,将实参的值复制一份给形参,函数内部对形参的修改不会影响到原始实参的值。
引用传递(pass by reference)是指在函数调用时,将实参的引用(地址)传递给形参,函数内部对形参的修改会影响到原始实参的值。
简单来说,值传递是对实参进行拷贝,函数内部的操作不会影响到原始实参;而引用传递是对实参的引用进行操作,函数内部的修改会影响到原始实参。

以上解释来自chatGpt

值传递和引用传递的对比如下:
在这里插入图片描述

三、实操

例子一

上个例子:

public static void main(String[] args) throws IOException {int i = 1;change(i);System.out.println(i);
}
public static void change(int a){a = 10;
}

输出:

1

图例:
在这里插入图片描述

由这个例子可见,i 的值还是1,change 方法并没有更改 i 的值,所以是不是可以得出 java 的方法传递是值传递?
那我们开始看下面这个

例子二

public static void main(String[] args) throws IOException {User user = new User();user.setName("yy");change(user);System.out.println(user.getName());
}
public static void change(User a){a.setName("xx");
}

同样是一个change方法,同样是在change方法内修改参数的值,输出:

xx

图例:
暂时无法在飞书文档外展示此内容

经过change方法执行后,实参的值被改变了,那按照上面2.2的引用传递的定义,实际参数的值被改变了,这不就是引用传递了么。那根据上面的两段代码,可以得出新的结论:Java的方法中,在传递普通类型的时候是值传递,在传递对象类型的时候是引用传递,真的是这样吗?其实这个表述还是有误的,不信看下面这个

例子三

public static void main(String[] args) throws IOException {String name = "yy";change(name);System.out.println(name);
}
public static void change(String input){input = "xx";
}

输出结果是:

yy

这个结果好像和上面的 在传递对象类型的时候是引用传递 的结论不符合。同样传递了一个对象,但是对象的原始值却没有改变;name为什么会是这样的呢,我们先来看下图例:
图例:
暂时无法在飞书文档外展示此内容

what?形参input 为啥会是新的内存地址呢?
其实,我们在change(name) 方法中想去修改name 的值,其实阴差阳错的直接修改了input 的应用地址,因为
input = “xx” 的背后是 会 new 一个 string ,把新的引用交给 input,等价于 input = new String(“xx”) 。原来的 “yy” 这个字符串还是由name 持有着,并没有修改到实际参数的值;所以 java 还是值传递,只不过对于对象参数,值是对象的引用地址;

好了,经过上面的概念理解和三个例子,大家应该基本了解了java 的参数传递,那我们把文章开头的例子改一下,输出会是什么样子呢?

public static void main(String[] args) throws IOException {List<String> mockList = Lists.newArrayList("a", "b");System.out.println("1: " + mockList);List<String> result = change(mockList);System.out.println("3: " + mockList);System.out.println("4: " + result);
}public static List<String> change(List<String> input){Collections.sort(input, Comparator.reverseOrder());System.out.println("2: " + input);List<String> result = input;return result;
}

输出:

1: [a, b]
2: [b, a]
3: [b, a]
4: [b, a]

有些同学可能会疑惑,为啥这里 3 输出的又是[b, a]呢,不是说java 是值传递, input 形参的修改不会影响到原来的 mockList 的内容吗?
其实 这里 Collections.sort(input, Comparator.reverseOrder()); 的问题,这个和 input.stream().sorted(Comparator.comparing(String::valueOf).reversed()).collect(Collectors.toList()); 的区别是:

  1. stream() 不会影响到原来集合的内容;Stream API 不会改变数据源,所有操作的最终结果会保存到另外一个对象中。(peek 方法除外,它会修改流中的元素)
  2. sort 却会改变原来内存地址指向的集合内容(本质是对List 内部的数组进行排序);

相关文章:

java 的参数传递

一、疑惑引入 首先&#xff0c;我们从一个例子来引出这个问题&#xff1a; public static void main(String[] args) throws IOException {List<String> mockList Lists.newArrayList("a", "b");System.out.println("1: " mockList);L…...

【面试长文】HashMap的数据结构和底层原理以及在JDK1.6、1.7和JDK8中的演变差异

文章目录 HashMap的数据结构和底层原理以及在JDK1.6、1.7和JDK8中的演变差异HashMap的数据结构和原理JDK1.6、1.7和1.8中的HashMap源码演变JDK1.6JDK1.7JDK1.8 总结自己实现一个简单的HashMapHashMap的时间复杂度分析HashMap的空间复杂度分析HashMap的应用场景HashMap的弊端及解…...

【25】linux进阶——网络文件系统NFS

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…...

JAVA入坑之JAVADOC(Java API 文档生成器)与快速生成

目录 一、JAVADOC&#xff08;Java API 文档生成器&#xff09; 1.1概述 1.2Javadoc标签 1.3Javadoc命令 1.4用idea自带工具生成API帮助文档 二、IDEA如何生成get和set方法 三、常见快捷方式 3.1快速生成main函数 3.2快速生成println()语句 3.3快速生成for循环 3.4“…...

React | React组件化开发

✨ 个人主页&#xff1a;CoderHing &#x1f5a5;️ React .js专栏&#xff1a;React .js React组件化开发 &#x1f64b;‍♂️ 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; &#x1f4ab; 系列专栏&#xff1a;吊打面试官系列 16天学会Vue 11天学会React Node…...

云计算的优势与未来发展趋势

一、前言二、云计算的基础概念2.1 云计算的定义2.2 云计算的发展历程2.3 云计算的基本架构2.4 云计算的主要服务模式 三、企业采用云计算的优势3.1 降低成本3.2 提高效率和灵活性3.3 提升信息系统的安全性和可靠性3.4 拥有更加丰富的应用和服务 四、行业应用案例4.1 金融行业4.…...

shell编程lesson01

命令行和脚本关系 命令行&#xff1a;单一shell命令&#xff0c;命令行中编写与执行&#xff1b; 脚本&#xff1a;众多shell命令组合成一个完成特定功能的程序&#xff0c;在脚本文件中进行编写维护。 脚本是一个文件&#xff0c;一个包含有一组命令的文件。 编写一个shel…...

看看人家的MyBatis批量插入数据优化,从120s到2.5s,那叫一个优雅!

粗略的实验 最后 最近在压测一批接口的时候&#xff0c;我发现接口处理速度比我们预期的要慢。这让我感到有点奇怪&#xff0c;因为我们之前已经对这些接口进行了优化。但是&#xff0c;当我们进行排查时&#xff0c;发现问题出在数据库批量保存这块。 我们的项目使用了 myb…...

软件和信息服务业专题讲座

软件和信息服务业专题讲座 单选题&#xff08;共 10 题&#xff0c;每题 3 分&#xff09; 1、根据本讲&#xff0c;我国要加强物联网应用领域&#xff08;&#xff09;开发和应用。 A、大数据 2、根据本讲&#xff0c;要充分发挥软件对城市管理和惠民服务的&#xff08;&am…...

由 ChatGPT 团队开发,堪称辅助神器!IntelliJ IDEA 神级插件

什么是Bito&#xff1f; 为什么要使用Bito&#xff1f; 如何安装Bito插件 如何使用Bito插件 什么是Bito&#xff1f; Bito是一款由ChatGPT团队开发的IntelliJ IDEA编辑器插件&#xff0c;旨在提高开发人员的工作效率。此插件强大之处在于它不仅可以帮助开发人员更快地提交…...

spass modeler

课时1&#xff1a;SPSS Modeler 简介 本课时一共分为五个模块&#xff0c;分别是Modeler概述、工具安装、窗口说明以及功能介绍和应用案例。相信通过本课时内容的学习&#xff0c;大家将会对SPSS Modeler有个基础的了解. 在学习本节课内容之前&#xff0c;先来看看本节课我们究…...

kafka的push、pull分别有什么优缺点

文章目录 kafka的push、pull分别有什么优缺点Push 模式优点缺点 Pull 模式优点缺点 实践操作 kafka的push、pull分别有什么优缺点 Kafka 是由 Apache 软件基金会开发的一个开源流处理平台&#xff0c;广泛应用于各大互联网公司的消息系统中。在 Kafka 中&#xff0c;生产者使用…...

【Canvas入门】从零开始在Canvas上绘制简单的动画

这篇文章是观看HTML5 Canvas Tutorials for Beginners教程做的记录&#xff0c;所以代码和最后的效果比较相似&#xff0c;教程的内容主要关于这四个部分&#xff1a; 创建并设置尺寸添加元素让元素动起来与元素交互 设置Canvas的大小 获取到canvas并设置尺寸为当前窗口的大…...

【技术整合】各技术解决方案与对应解决的问题

文章目录 基本实现性能安全 本文将框架分为三大类&#xff1a; 基本实现&#xff1a;包括某个供能或者提供web、移动端、桌面端、或者上述端上的某种功能性能&#xff1a;提升高可用、高并发的框架安全&#xff1a;包括网络安全、权限与容灾等 基本实现 .NET CORE、.NET web基…...

公网远程访问公司内网象过河ERP系统「内网穿透」

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻&#xff0c;不管是财务、生产、销售还是采购&#xff0c;都需要用到ERP系统来协助。…...

Win11的两个实用技巧系列之修改c盘大小方法、功能快捷键大全

Win11 c盘无法更改大小什么原因?Win11修改c盘大小方法 有不少朋友反应Win11 c盘无法更改大小是怎么回事&#xff1f;本文就为大家带来了详细的更改方法&#xff0c;需要的朋友一起看看吧 Win11 c卷无法更改大小什么原因&#xff1f;有用户电脑的系统盘空间太小了&#xff0c;…...

离散数学下--- 代数系统

代数系统 定义&#xff1a; 代数系统是用代数运算构造数学模型的方法。 • 通过构造手段生成&#xff0c;所以也称代数结构 • 代数运算&#xff1a;在集合上建立满足一定规则的运算系统 &#xff08;一&#xff09;二元运算 二元运算的定义 二元运算需要满足的两个条件&a…...

java基础入门-04

Java基础入门-04 11、集合&学生管理系统11.1.ArrayList集合和数组的优势对比&#xff1a;11.1.1 ArrayList类概述11.1.2 ArrayList类常用方法11.1.2.1 构造方法11.1.2.2 成员方法11.1.2.3 示例代码 11.1.3 ArrayList存储字符串并遍历11.1.3.1 案例需求11.1.3.2 代码实现 11…...

《面试1v1》java反射

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 你好&#xff0c;请问你对 Java 反射有了解吗&#xff1f; 候选人&#xff1a; 是的&#xff0c;我了解一些。 面试官&#xff1a; 那你能简单…...

【C语言】struct结构体

文章目录 一. 结构体简述二. 结构体的声明和定义1、简单地声明一个结构体和定义结构体变量2、声明结构体的同时也定义结构体变量3、匿名结构体4、配合typedef&#xff0c;声明结构体的同时为结构体取别名5、在声明匿名结构体时&#xff0c;使用typedef给这个匿名结构体取别名 三…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...