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;}
}
详细步骤
  1. 定义主方法 calculateTotalPages

    • 初始化 totalPageCount 为 0。
    • 遍历文件列表,调用 processFile 方法处理每个文件。
    • 更新 totalPageCountprocessFile 方法返回的新值。
    • 返回最终的 totalPageCount
  2. 定义辅助方法 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 中方法参数传递的一个常见陷阱。对于基本类型,方法内部的修改不会影响到方法外部的变量。为了避免这种情况,可以通过返回新的值并在方法外部更新变量来解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/56638.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ORA-65096:公用用户名或角色名无效

CREATE USER DATA_SHARING IDENTIFIED BY "Ab2"; Oracle建立用户的的时候&#xff0c;可能会出现一直提示 ORA-65096:公用用户名或角色名无效&#xff1b; 我查了一下&#xff0c;好像是 oracle 12版本及以上版本的特性&#xff0c;用户名必须加c##或者C##前缀才能创…

三勾软件/ java+springboot+vue3玖玖云电商ERP多平台源码

玖玖云ERP系统、支持多平台订单同步&#xff0c;仓库发货&#xff0c;波次拣货&#xff0c;售后服务&#xff0c;电商ERP一站式解决方案 项目介绍 玖玖云ERP系统基于javaspringbootelement-plusuniapp打造的面向开发的电商管理ERP系统&#xff0c;方便二次开发或直接使用。主…

FFmpeg的简单使用【Windows】

目录 一、视频生成图片 静态图片 转码过程 动态图片gif 二、图片生成视频 三、FFmpeg常用参数命令 3.1 主要参数 3.1.1、-i 3.1.2、-f 3.1.3、-ss 3.1.4、-t 3.2 音频参数 3.2.1、-aframes 3.2.2、 -b:a 3.2.3、-ar 3.2.4、-ac 3.2.5、-acodec 3.2.6、-an 3…

HarmonyOS中ArkUi框架中常用的装饰器

目录 1.装饰器 1&#xff09;Component 1--装饰内容 2&#xff09;Entry 1--装饰内容 2--使用说明 3&#xff09;Preview 1--装饰内容 2--使用说明 4&#xff09;CustomDialog 1--装饰内容 2--使用说明 5&#xff09;Observed 1--装饰内容 2--使用说明 6&#xff09;ObjectLin…

【实战篇】用SkyWalking排查线上[xxl-job xxl-rpc remoting error]问题

一、组件简介和问题描述 SkyWalking 简介 Apache SkyWalking 是一个开源的 APM&#xff08;应用性能管理&#xff09;工具&#xff0c;专注于微服务、云原生和容器化环境。它提供了分布式追踪、性能监控和依赖分析等功能&#xff0c;帮助开发者快速定位和解决性能瓶颈和故障。…

【机器学习(十三)】零代码开发案例之股票价格预测分析—Sentosa_DSML社区版

文章目录 一、背景描述二、Sentosa_DSML社区版算法实现(一) 数据读入(二) 特征工程(三) 样本分区(四) 模型训练和评估(五) 模型可视化 三、总结 一、背景描述 股票价格是一种不稳定的时间序列,受多种因素的影响。影响股市的外部因素很多,主要有经济因素、政治因素和公司自身因素…

ASP.NET Core8.0学习笔记(二十)——EFCore导航属性与外键

一、什么是实体间关系 数据库表&#xff08;实体&#xff09;之间的关系&#xff1a;一对一&#xff08;学生-成绩&#xff09;、一对多&#xff08;学生-科目&#xff09;、多对多&#xff08;教师-班级&#xff09;。数据库中&#xff0c;每一个实体可以由主键唯一标识&…

MySQL表的基本查询下/分组聚合统计

1&#xff0c;update 对查询到的结果进行列值更新&#xff0c;可以和older by&#xff0c;where&#xff0c;limit合并使用&#xff0c;为了方便讲解&#xff0c;将会以题目练习的方式进行说明&#xff1a; 1&#xff0c;将孙悟空同学的数学成绩变更为 80 分 本道题和where联…

动态规划(1)斐波那契数列模型

动态规划算法流程&#xff1a; 1、状态表示&#xff1a; 指的是dp&#xff08;dynamic programming&#xff09;表里面的值所表示的含义 如何得出&#xff1a;1、题目要求 2、经验题目要求 3、分析问题的过程中发现重复子问题 2、状态转移方程 dp[i]等于什么 3、初始化 保证…

dbt doc 生成文档命令示例应用

DBT提供了强大的命令行工具&#xff0c;它使数据分析师和工程师能够更有效地转换仓库中的数据。dbt的一个关键特性是能够为数据模型生成文档&#xff0c;这就是dbt docs命令发挥作用的地方。本教程将指导您完成使用dbt生成和提供项目文档的过程。 dbt doc 命令 dbt docs命令有…

案例实践 | 以长安链为坚实底层,江海链助力南通民政打造慈善应用标杆

案例名称-江海链 ■ 实施单位 中国移动通信集团江苏有限公司南通分公司、中国移动通信集团江苏有限公司 ■ 业主单位 江苏省南通市民政局 ■ 上线时间 2023年12月 ■ 用户群体 南通市民政局、南通慈善总会等慈善组织及全市民众 ■ 用户规模 全市近30家慈善组织&#…

leetcode二叉树(八)-二叉树的最大深度

题目 104.二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&…

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波 前言MPU6050寄存器代码详解mpu6050.cmpu6050.h 使用说明 前言 本篇文章基于卡尔曼滤波的原理详解与公式推导&#xff0c;来详细的解释下如何使用卡尔曼滤波来解算MPU6050的姿态 参考资料&#xff1a;Github_mpu6050 MPU6050寄存器…

项目管理软件真的能让敏捷开发变得更简单吗?

敏捷开发是一种以快速交付和适应变化为核心特点的软件开发方法。其特点包括尽早并持续交付、能够驾驭需求变化、版本周期内尽量不加任务、业务与开发协同工作、以人为核心、团队配置敏捷等。 例如&#xff0c;尽早并持续交付可使用的软件&#xff0c;使客户能够更早地体验产品…

【算法篇】动态规划类(4)——子序列(笔记)

目录 一、Leetcode 题目 1. 最长递增子序列 2. 最长连续递增序列 3. 最长重复子数组 4. 最长公共子序列 5. 不相交的线 6. 最大子序和 7. 判断子序列 8. 不同的子序列 9. 两个字符串的删除操作 10. 编辑距离 11. 回文子串 12. 最长回文子序列 二、动态规划总结 …

[Linux#67][IP] 报头详解 | 网络划分 | CIDR无类别 | DHCP动态分配 | NAT转发 | 路由器

目录 一. IP协议头格式 学习任何协议前的两个关键问题 IP 报头与有效载荷分离 分离方法 为什么需要16位总长度 如何交付 二. 网络通信 1.IP地址的划分理念 2. 子网管理 3.网络划分 CIDR&#xff08;无类别域间路由&#xff09; 目的IP & 当前路由器的子网掩码 …

外包干了3周,技术退步太明显了。。。。。

先说一下自己的情况&#xff0c;大专生&#xff0c;21年通过校招进入武汉某软件公司&#xff0c;干了差不多3个星期的功能测试&#xff0c;那年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我才在一个外包企业干了3周的功…

神经网络构建与训练深度学习模型全过程(PyTorch TensorFlow)

神经网络构建与训练深度学习模型全过程&#xff08;PyTorch & TensorFlow&#xff09; 目录 &#x1f517; 什么是神经网络&#xff1a;基础架构与工作原理&#x1f9e9; 构建简单的神经网络&#xff1a;层次结构与激活函数&#x1f680; 前向传播&#xff1a;神经网络的…

基于Handsontable.js + Excel.js实现表格预览和导出功能(公式渲染)

本文记录在html中基于Handsontable.js Excel.js实现表格预览、导出、带公式单元格渲染功能&#xff0c;在这里我们在html中实现&#xff0c;当然也可以在vue、react等框架中使用npm下载导入依赖文件。 Handsontable官方文档 一、开发前的准备引入相关依赖库 <!DOCTYPE ht…

微服务经典应用架构图

从网上找了一个经典的微服务架构图&#xff0c;资料来源于若依开源系统的ruoyi-cloud&#xff0c;仅供参考&#xff01;