当前位置: 首页 > 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给这个匿名结构体取别名 三…...

AI原生推荐:如何实现端到端的训练?

AI原生推荐&#xff1a;如何实现端到端的训练&#xff1f;关键词&#xff1a;AI原生推荐、端到端训练、深度学习推荐系统、推荐模型架构、多模态融合摘要&#xff1a;本文将从“AI原生推荐”的核心需求出发&#xff0c;用“快递物流”“餐厅点菜”等生活化类比&#xff0c;逐步…...

基于.NET 11 与C# 14的高性能安全客户端应用开发

基于.NET 11 与C# 14的高性能安全客户端应用开发 前言 在客户端应用开发领域&#xff0c;性能与安全始终是关键指标。随着.NET 11 和 C# 14 的推出&#xff0c;开发者拥有了更强大的工具来构建高性能且安全可靠的客户端应用。这些新技术不仅提升了应用的运行效率&#xff0c;还…...

高分二号卫星全解析:从光谱波段到城市管理的实战应用

1. 高分二号卫星的技术参数详解 高分二号卫星作为我国首颗亚米级高分辨率民用光学遥感卫星&#xff0c;其技术参数直接决定了它在城市管理中的应用能力。先说说最核心的空间分辨率&#xff1a;全色波段0.8米意味着能清晰识别小轿车级别的物体&#xff0c;多光谱3.2米分辨率则适…...

Python办公自动化:用PyMuPDF+pdfplumber一键提取PDF文字/图片/表格(附完整代码)

Python办公自动化实战&#xff1a;PyMuPDF与pdfplumber高效提取PDF三要素 每天面对堆积如山的PDF文档&#xff0c;行政和财务人员最头疼的莫过于手动复制粘贴文字、截图保存图片、重新绘制表格。我曾见过一位财务同事为了处理200份供应商报价单&#xff0c;连续加班一周手工录入…...

Unsloth让AI触手可及:免费GPU+开源框架,训练自己的模型

Unsloth让AI触手可及&#xff1a;免费GPU开源框架&#xff0c;训练自己的模型 1. Unsloth简介&#xff1a;高效微调的开源利器 Unsloth是一个专为大型语言模型(LLM)优化的开源微调框架&#xff0c;它的核心使命是让AI训练变得高效且易于获取。通过创新的技术手段&#xff0c;…...

MiniCPM-o-4.5-nvidia-FlagOS与ChatGPT对比评测:代码生成与逻辑推理

MiniCPM-o-4.5-nvidia-FlagOS与ChatGPT对比评测&#xff1a;代码生成与逻辑推理 最近在开发者圈子里&#xff0c;关于开源大模型和闭源大模型谁更强的讨论一直没停过。特别是涉及到代码生成和逻辑推理这种硬核任务&#xff0c;大家心里都有一杆秤。今天&#xff0c;我们就拿一…...

GitHub贡献统计性能优化终极指南:5个关键技巧提升Streak Stats响应速度

GitHub贡献统计性能优化终极指南&#xff1a;5个关键技巧提升Streak Stats响应速度 【免费下载链接】github-readme-streak-stats &#x1f525; Stay motivated and show off your contribution streak! &#x1f31f; Display your total contributions, current streak, and…...

别再死磕公式了!用Ansoft Maxwell 2D给永磁无刷电机做仿真,保姆级操作流程(附避坑点)

永磁无刷电机仿真实战&#xff1a;从零掌握Ansoft Maxwell 2D的高效工作流 第一次打开Ansoft Maxwell 2D时&#xff0c;满屏的专业术语和复杂的参数设置界面确实容易让人望而生畏。作为从业十年的电机设计工程师&#xff0c;我完全理解这种面对专业仿真软件时的无力感——理论书…...

动态规划专练:力扣第509、70、746题

由于对动态规划DP算法 掌握得不是很好&#xff0c;所以决定进行动态规划专项训练。动态规划五部曲①确定dp[i]含义②递推公式③dp数组如何初始化④遍历顺序⑤打印dp数组&#xff08;debug&#xff09;除了第五条在力扣上不开会员无法实现外&#xff0c;其余四项就是做出dp类型题…...

如何用League-Toolkit实现英雄联盟游戏自动化:3个核心模块深度解析

如何用League-Toolkit实现英雄联盟游戏自动化&#xff1a;3个核心模块深度解析 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit Le…...