Java 中方法参数传递的陷阱
前言
在编程过程中,我们经常会遇到一些看似简单却容易出错的问题。本文将通过一个具体的例子,探讨 Java 中方法参数传递的陷阱,并提供详细的解决方法。希望这篇文章能帮助你在未来的开发中避免类似的错误。
问题背景
假设我们的任务是计算多个文件的总页数。为了实现这一目标,我们编写了一个主方法 calculateTotalPages
和一个辅助方法 processFile
。我们的预期是在每次处理完一个文件后,累加该文件的页数到总页数中。然而,当我们运行代码时,发现总页数并没有正确累加。
示例代码
首先,我们来看一下原始的示例代码:
import java.util.Arrays;
import java.util.List;public class PageCalculator {public static void main(String[] args) {List<String> files = Arrays.asList("file1.pdf", "file2.pdf", "file3.pdf");int totalPages = calculateTotalPages(files);System.out.println("Total pages: " + totalPages);}public static int calculateTotalPages(List<String> files) {int totalPageCount = 0;for (String file : files) {processFile(file, totalPageCount); // 这里传递了totalPageCount}return totalPageCount; // totalPageCount没有被更新}public static void processFile(String file, int pageCount) { // 参数pageCount是按值传递int pagesInFile = getPagesInFile(file);pageCount += pagesInFile; // 修改不会影响外部变量System.out.println("Processed " + file + " with " + pagesInFile + " pages. Total pages now: " + pageCount);}public static int getPagesInFile(String file) {// 模拟获取文件页数return file.length() / 4;}
}
问题分析
- 按值传递:Java中的方法参数是按值传递的。对于基本类型(如
int
),方法内部对参数的修改不会影响到方法外部的变量。 - 在
calculateTotalPages
方法中,totalPageCount
被传递给processFile
方法,但在processFile
方法内部对pageCount
的修改并不会影响到totalPageCount
。 - 代码执行过程:
- 每次调用
processFile
方法时,pageCount
都会被初始化为totalPageCount
的当前值。 - 在
processFile
方法内部,pageCount
被累加了文件的页数,但这个修改只在方法内部生效。 - 当
processFile
方法返回时,totalPageCount
仍然保持不变。
- 每次调用
解决方法
为了让processFile
方法能够正确地更新总页数,我们需要让processFile
方法返回一个新的pageCount
值,并在calculateTotalPages
方法中接收并更新totalPageCount
。
修改后的代码
下面是修改后的代码示例:
import java.util.Arrays;
import java.util.List;public class PageCalculator {public static void main(String[] args) {List<String> files = Arrays.asList("file1.pdf", "file2.pdf", "file3.pdf");int totalPages = calculateTotalPages(files);System.out.println("Total pages: " + totalPages);}public static int calculateTotalPages(List<String> files) {int totalPageCount = 0;for (String file : files) {totalPageCount = processFile(file, totalPageCount); // 更新totalPageCount}return totalPageCount;}public static int processFile(String file, int pageCount) {int pagesInFile = getPagesInFile(file);pageCount += pagesInFile; // 累加文件页数System.out.println("Processed " + file + " with " + pagesInFile + " pages. Total pages now: " + pageCount);return pageCount; // 返回新的pageCount}public static int getPagesInFile(String file) {// 模拟获取文件页数return file.length() / 4;}
}
详细步骤
-
定义主方法
calculateTotalPages
:- 初始化
totalPageCount
为 0。 - 遍历文件列表,调用
processFile
方法处理每个文件。 - 更新
totalPageCount
为processFile
方法返回的新值。 - 返回最终的
totalPageCount
。
- 初始化
-
定义辅助方法
processFile
:- 获取文件的页数。
- 将文件的页数累加到
pageCount
。 - 打印当前的总页数。
- 返回更新后的
pageCount
。
代码解释
main
方法:程序入口点,创建文件列表,调用calculateTotalPages
计算总页数,并输出结果。calculateTotalPages
方法:遍历文件列表,调用processFile
处理每个文件,并更新totalPageCount
。processFile
方法:接收文件名和当前页数计数器,计算文件的页数,累加到pageCount
,打印当前总页数,并返回更新后的pageCount
。getPagesInFile
方法:模拟获取文件的页数,这里简单地用文件名长度除以 4 来表示。
运行结果
当程序运行时,输出如下:
Processed file1.pdf with 3 pages. Total pages now: 3
Processed file2.pdf with 3 pages. Total pages now: 6
Processed file3.pdf with 3 pages. Total pages now: 9
Total pages: 9
核心思路
- 理解按值传递:Java 中的基本类型的参数是按值传递的,这意味着方法内部对这些参数的修改不会影响到方法外部的变量。
- 返回新的值:通过让方法返回新的值,并在方法外部更新变量,可以确保变量的值在多次调用中正确累加。
总结
通过上述示例,我们可以看到 Java 中方法参数传递的一个常见陷阱。对于基本类型,方法内部的修改不会影响到方法外部的变量。为了避免这种情况,可以通过返回新的值并在方法外部更新变量来解决问题。
相关文章:
Java 中方法参数传递的陷阱
前言 在编程过程中,我们经常会遇到一些看似简单却容易出错的问题。本文将通过一个具体的例子,探讨 Java 中方法参数传递的陷阱,并提供详细的解决方法。希望这篇文章能帮助你在未来的开发中避免类似的错误。 问题背景 假设我们的任务是计算…...

哪家云电脑便宜又好用?ToDesk云电脑、顺网云、达龙云全方位评测
陈老老老板🤴 🧙♂️本文专栏:生活(主要讲一下自己生活相关的内容)生活就像海洋,只有意志坚强的人,才能到达彼岸。 🧙♂️本文简述:讲一下市面上云电脑的对比。 🧙♂️上一篇文…...

【汇编语言】寄存器(内存访问)(三)—— 字的传送
文章目录 前言1. 字的传送2. 问题一3. 问题一的分析与解答4. 问题二5. 问题二的分析与解答结语 前言 📌 汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言…...
6 机器学习之应用现状
在过去二十年中,人类收集、存储、传输、处理数据的能力取得了飞速提升,人类社会的各个角落都积累了大量数据,亟需能有效地对数据进行分析利用的计算机算法,而机器学习恰顺应了大时代的这个迫切需求,因此该学科领域很自…...

相似度为 K 的字符串
题目链接 相似度为 K 的字符串 题目描述 注意 s1和s2只包含集合 {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’} 中的小写字母s2是s1的一个字母异位词 解答思路 可以深度优先遍历交换字母使得s1和s2尽可能接近,基本思路是:设定一个指针idx指向s1和s2的…...
[云] Project Analysis
项目要求分析: 开放性选题: 主题范围:任何与云计算系统相关的主题。项目类型:可以是技术、商业或研究项目。团队规模:最多可组成三人小组。 示例主题: 分析公共云数据:例如,AWS公共数…...

腾讯六宫格本地识别,本地模型识别,腾讯六图识别
基于K哥爬虫昨天发的文章,特此训练了一版腾讯模型,效果不错,特此感谢K哥的指导,效果如下图: 有需求,有疑问的欢迎评论区点出...

Transformer图解以及相关的概念
前言 transformer是目前NLP甚至是整个深度学习领域不能不提到的框架,同时大部分LLM也是使用其进行训练生成模型,所以transformer几乎是目前每一个机器人开发者或者人工智能开发者不能越过的一个框架。接下来本文将从顶层往下去一步步掀开transformer的面…...
Nginx缓存静态文件
在Python项目中,通过Nginx缓存静态文件(如CSS、JS、图片等),可以有效提升网页的加载性能。Nginx可以帮助你缓存静态资源,减少服务器负担,并加速页面加载。 1. 配置Nginx缓存静态文件 首先,你需…...

【隐私计算】隐语HEU同态加密算法解读
HEU: 一个高性能的同态加密算法库,提供了多种 PHE 算法, 包括ZPaillier、FPaillier、IPCL、Damgard Jurik、DGK、OU、EC ElGamal 以及基于FPGA和GPU硬件加速版本的Paillier版本。 本文我们会基于GPU运行HEU Docker容器,编译打包GPaillier并测…...
用C#实现互斥操作
1、传统的lock lock简单易用,适合大多数场景,但在高竞争用情况下可能会导致线程阻塞; Object obj new object(); void method1(){lock (obj){// 进行互斥操作}}2、SpinLock SpinLock在低延迟情况下更有效,因为SpinLock会在忙等…...

【黑马点评优化】之使用Caffeine+Redis实现应用级二层缓存
【黑马点评优化】之使用CaffeineRedis实现应用级二层缓存 1 缓存雪崩定义及解决方案2 为什么要使用多级缓存3 RedisCaffeine实现应用层二级缓存原理4 利用CaffeineRedis解决Redis突然宕机导致的缓存雪崩问题4.1 pom.xml文件引入相关依赖4.2 本地缓存配置类4.3 修改ShopServiceI…...

CEEMDAN +组合预测模型(BiLSTM-Attention + ARIMA)
往期精彩内容: 时序预测:LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享! EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现(一)EMD-CSDN博客 EMD、EEM…...
2.1.ReactOS系统中断描述符的格式KIDTENTRY结构体
2.1.ReactOS系统中断描述符的格式KIDTENTRY结构体 2.1.ReactOS系统中断描述符的格式KIDTENTRY结构体 文章目录 2.1.ReactOS系统中断描述符的格式KIDTENTRY结构体KIDTENTRY KIDTENTRY 数据结构KIDTENTRY定义了CPU对中断描述符的格式 // // …...

三、ElementPlus下拉搜索加弹窗组件的封装
近期产品提出了一个需求,要求一个form的表单里面的一个组件既可以下拉模糊搜索,又可以弹窗搜索,我就为这个封装了一个组件,下面看效果图。 效果大家看到了,下面就看组件封装和实现方法 第一步,组件封装&…...

androidStudio编译导致的同名.so文件冲突问题解决
files found with path lib/arm64-v8a/libserial_port.so from inputs: ...\build\intermediates\library_jni\debug\jni\arm64-v8a\libserial_port.so C:\Users\...\.gradle\caches\transforms-3\...\jni\arm64-v8a\XXX.so 解决方式如下: 1.将gradle缓存文件删…...

大学新生编程入门指南:如何选择编程语言与制定学习计划
大学新生编程入门指南:如何选择编程语言与制定学习计划 编程已成为当代大学生的必备技能,尤其是在信息技术高速发展的今天,编程能力不仅能帮助你在课堂学习中脱颖而出,更能为未来职业生涯打下坚实的基础。然而,面对如…...

SpringAI快速上手
一、导入依赖 镜像(导入maven依赖) <repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>…...

07 django管理系统 - 部门管理 - 搜索部门
在dept_list.html中,添加搜索框 <div class"container-fluid"><div style"margin-bottom: 10px" class"clearfix"><div class"panel panel-default"><!-- Default panel contents --><div clas…...

数据操作学习
1.导入torch。虽然被称为PyTorch,但应导入torch而不是pytorch import torch 2.张量表示一个数值组成的数组,这个数组可能有多个维度 xtorch.arange(12)x 3.通过张量的shape属性来访问张量的形状和张量中元素的总数 x.shape x.numel() 4.要改变张量的形…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...