当前位置: 首页 > 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 Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

flow_controllers

关键点&#xff1a; 流控制器类型&#xff1a; 同步&#xff08;Sync&#xff09;&#xff1a;发布操作会阻塞&#xff0c;直到数据被确认发送。异步&#xff08;Async&#xff09;&#xff1a;发布操作非阻塞&#xff0c;数据发送由后台线程处理。纯同步&#xff08;PureSync…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...