记一次Java参数传递时值发生变化问题

【信息科学与工程学】计算机科学与自动化——第二十四篇 编译器04 LLVM编译器02 B-WUCL(用户权重均匀对比损失)和D-WUCL(物品权重均匀对比损失)中,动态调整参数λ_new(新用户补偿因子)和α(长尾补偿强度)是优化推荐系统适应数据分布变化的核心。 阅读详情

0.前景回顾

代码内容如下:

private boolean dfs(char[][] board, int[][] k, String word, int index, int i, int j) {
    if (index >= word.length()) {
        return true;
    }
    if (i >= board.length || i < 0 || j < 0 || j >= board[0].length) {
        return false;
    }
    // 已使用
    if (k[i][j] == 1 || board[i][j] != word.charAt(index)) {
        return false;
    }
  	// 问题行
    k[i][j] = 1;
    return dfs(board, k, word, index + 1,i - 1, j)
            || dfs(board, k, word, index + 1,i + 1, j)
            || dfs(board, k, word, index + 1,i, j - 1)
            || dfs(board, k, word, index + 1,i, j + 1);
}

上面中所标识的问题行代码主要是想让k数组所在的地方进行标识,然后以相同的状态传递给后续调用的四次dfs方法。

但是,在实际的运行过程中发现最后一次dfs调用时k数组中的值和一开始不一样!!!!!

看见这种现象立马想到的是参数传递问题,子方法的调用将父方法中的值修改了。后面就在方法的调用上将k改为了k.clone(),发现还是不行(之前明明记得clone返回的不会影响原对象)。

1. 值传递 or 引用传递?

这两个概念在用C写代码的时候很常见,但是Java到底是属于哪种呢?

  • 值传递:通俗的讲就是将变量具体的值拿来传递给方法,也可以认为形参是实参的一个副本;
  • 引用传递:传递的是变量的地址,操作形参相当于操作实参一样。

拓展:形参和实参

形参:方法定义中的参数,像最上面例子中board,k,i这些都是形参;

实参:在调用方法时实际传入的。

第一个例子

@Test
public void test() {
    int x = 1;
    System.out.println("main: " + x);
    change(x);
    System.out.println("after change main: " + x);
}

public void change(int x) {
    x = 10;
    System.out.println("change : " + x);
}

结果:

main: 1
change : 10
after change main: 1

可以看到change方法中将参数的值修改成了10,主方法中的值并没有发生变化。

接着将参数类型改为变量:

@Test
public void test() {
    User user = new User(1, "John");
    System.out.println("before change : " + user);
    change(user);
    System.out.println("after change : " + user);

}

public void change(User user) {
    // user = new User(user.id, user.name);
    user.setName("April");
    System.out.println("changer : " + user);

}

返回:

before change : User{id=1, name=‘John’}
changer : User{id=1, name=‘April’}
after change : User{id=1, name=‘April’}

这里的值被change给修改了,难道就是引用传递?

将上段代码中注释掉的行取消注释;

返回

before change : User{id=1, name=‘John’}
changer : User{id=1, name=‘April’}
after change : User{id=1, name=‘John’}

关键来了。。。

如果说对象用的是引用传递,那么在change方法中重新new了一个新的对象(值还是原来的),然后修改新对象的值,主方法中打印出来的对象属性应该和change方法中的一致。

但是,上面明明也可以修改原对象的值,这又是为什么?

可以这么认为,在传递参数的时候,是用原对象的副本(指向实际的地址)来传递,在函数中是可以执行修改对应实际地址中的值,所以主方法中会同样感知到修改。

在这里插入图片描述

但是如果将方法中的参数指向新的地址,比如new 一个新的对象或者将别的对象重新赋值给参数,这样形参和实参指向的就不是同一个地址空间,任何修改都不会引起原对象的变化。

在这里插入图片描述

2.clone()

具体clone的内容这里不作分析,主要看看最上面问题所反映的现象。

下面是相关两个场景的测试用例:

@Test
public void cp1() {
    int[] array = new int[]{1,2,3};
    System.out.println("before :" + Arrays.toString(array));
    int[] cloneArray = array.clone();
    cloneArray[0] = 0;
    System.out.println("after :" + Arrays.toString(array));
}

返回

before :[1, 2, 3]
after :[1, 2, 3]

@Test
public void cp2() {
    int[][] array = new int[][]{{1,2,3}};
    System.out.println("before :" + Arrays.toString(array[0]));
    int[][] cloneArray = array.clone();
    cloneArray[0][0] = 0;
    System.out.println("after :" + Arrays.toString(array[0]));
}

返回

before :[1, 2, 3]
after :[0, 2, 3]

上面两个例子中唯一区别的就是实际参与的对象一个是一维数组,一个是二维数组。从结果中可以看出,一维数组clone出来的对象修改不会影响到原对象,而二维数组会影响。

clone是浅拷贝的,对于多维数组而言,每个数组元素也是一个数组对象,当利用clone进行拷贝的时候是不会对数组中的对象进行拷贝,所以会影响原对象中值。对于多维数组要达到副本的效果就需要对每个数组中的元素(数组)再进行一次clone。

3. 解决思路

目标效果

  • 将数组传递给子方法后,子方法调用结束,原数组中的值不变。

解决方法

  • 每次传递给方法的是数组深拷贝的副本;
  • 在方法中修改完数组中的值后,在方法结束之前恢复原来的值。
吹气压力传感器US6310 US6330调试 更换压力传感器, 从US6310 更换为US6330。 6310有一个准备好引脚,AD转换完成后会给MCU一个脉冲 而6330就没有这个功能,6330这个引脚是用来选择SPI还是I2C接口的。(6330没有复位引脚,内部有POR功能) 因此在实现上是有根本区别的, 其它方面使用的命令也不一样, 6310 A8 A9两条命令,一个命令模块醒来,一个命令模块休眠, 6330只有一条命令AA, 命令模块开始转换。 针对这2个模块作为2种处理方法, 1. 6310,可以设置一... 阅读详情

相关推荐

SecureCRT 9.0最新版安装与激活全攻略(附驱动识别技巧)

本文提供SecureCRT 9.0最新版的详细安装与激活指南,并重点解析了嵌入式开发中串口连接的硬件驱动识别技巧。内容涵盖从安全获取软件、解决USB转串口驱动兼容性问题,到配置SSH与串口会话的完整流程,旨在帮助开发者和工程师高效部署并精通使用这款终端仿真利器。

star的博客 410

Java参数传递造成参数值改变的情况--值传递和引用传递的初步理解

值传递 值传递,像int,float之类的简单类型进行的是值传递 public static void main(String[] args) { int i = 900; System.out.println(i); changeInt(i); System.out.println(i); } public static void changeInt(int

Android_Robot的专栏 7769

gsplat在windows本地部署

3DGS的cuda提效和优化内存的版本gsplat,使得在有一定GPU计算能力的电脑上也能够尝尝3DGS的效果。我在2025年的开年之初尝试配置过gsplat,由于过程中遇到很多问题,最终还是有一些windows上字符编码的问题,没有跑通,最近看gsplat的github更新了3DGUT,优化了反射和二次折射,以及适用于非线性相机模型,如鱼眼相机等。在data目录下下载好了360_v2的数据,进入之后images文件夹是原始分辨率的图像,images_2是下采样系数为2的数据,以此类推。

yuleaf_csdn的博客 2370

Java 变量参数传入方法,修改后是否影响外面的值

public class Test2 { public static void setValue(String str){ str = "ss"; } public static void setValue(Man str){ str = new Man("test"); } public static class Ma...

fenglllle的博客 3万+

ros_gz_bridge__镜像__readme

Run。

1113

Cadence OrCAD Capture软件启动过程卡死且无法恢复的解决方法

如下图所示Cadence OrCAD Capture软件在启动后出现卡死的现象,且等待后无法自动恢复,需要强行关闭,再次启动依然卡死。

fydar的博客 4044

java中调用方法传值问题详解

背景 最近,我在用java写代码过程中遇到了这么个情况:通过调用 方法 来修改 值,有时候能成功,有时候却失败,让我百思不得其解。于是,这篇博文诞生了,与大家一起分享一下我的使用心得。 基础知识 想要搞清楚这个问题之前,我们得清楚的明白:在 java 中有哪些数据类型。 java中的数据类型,分为两类:基本数据类型和引用数据类型 基本数据类型: 基本数据类型 整数类型 int、long、short、byte 浮点类型 float、double 字符类型 .

我想月薪过万的博客 1286

Open3D 合并两个点云【2025最新版】

两个点云中的数据连接,博客长期更新,本文最新更新时间为:2025年4月26日。

点云侠的博客 7435

Java参数在方法中传递发生的值改变

Java参数在方法中传递发生的值改变

m0_56337658的博客 1521

华为OD面试手撕真题 - 最大数

华为OD面试手撕真题 最大的数 提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 342

【量化入门】Tushare库获取公募基金的历史净值

在本文中,我们将介绍如何使用Python的Tushare库获取公募基金的历史净值。

木头大左的博客 1144

java 之方法调用 方法传参 值传递还是引用传递字节码

/*Java中的参数传递方式到底是引用传递还是值传递?java核心技术卷I里有一个结 论我觉得挺有意思的:java中没有引用传递,只有值传递 首先看定义: 值传递,是指方法接收的是调用者提供的值 引用传递,是指方法接收的是调用者提供的变量地址 事实上,Java中方法参数传递的是原来对象引用的copy(副本)。如果你在方法 中改变这个copy中的内容,因为这个copy也是指

xiaomin1991222的专栏 1157

飞牛NAS系统盘占用过高排查与解决全记录(已有效解决)

📢NAS弹出系统盘占用过高预警?别慌!亲测解决全流程来啦~ 精准定位根源+安全迁移数据,附详细实操步骤,帮同款困扰的你高效释空间、少走弯路!

XiaoqiangClub的博客 3137

java变换变量赋值_Java变量的类型转换

在程序中,当把一种数据类型的值赋给另一种数据类型的变量时,需要进行数据类型转换。根据转换方式的不同,数据类型转换可分为两种:自动类型转换和强制类型转换。自动类型转换自动类型转换也叫隐式类型转换,指的是两种数据类型在转换的过程中不需要显式地进行声明。要实现自动类型转换,必须同时满足两个条件,第一是两种数据类型彼此兼容,第二是目标类型的取值范围大于源类型的取值范围。例如:byteb=3;int...

weixin_34352414的博客 653

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

局部变量被莫名的改变如何处理

局部变量被莫名的改变如何处理

QuanQuanYuanXin的博客 1277

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

2. 变量

变量的分类: 1.局部变量:声明在方法中的变量 2.成员变量:声明在类中方法外 3.静态变量:使用static 关键词修饰的变量,一般在类中方法外 局部变量:值一旦变化,可以通过代码改变值 声明格式:数据类型 变量名=值;"="是赋值,把值赋给变量。 数据类型:整数:int 小数:double 局部变量的使用注意事项:使用之前要初始化(赋初值) 变量的操作:1.赋值 2.改变变量值 声明一个常量(不能通过代码进行改变)格式:final 数据类型 常量名=值............

qq_58731454的博客 329

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java外部变量作为参数传递到方法时,值发生变化问题

首先看一下这个问题。 Java值传递 or 引用传递? 这两个概念在用C写代码的时候很常见,但是Java到底是属于哪种呢? 值传递:通俗的讲就是将变量具体的值拿来传递给方法,也可以认为形参是实参的一个副本。 引用传递:传递的是变量的地址,操作形参相当于操作实参一样。 1、创建User对象,以及Activity和layout。 public class User { private String name; private String sex; private i

UrasakiNakajima的博客 2411

java方法参数传递,对传入值的影响

java方法参数传递,对传入值的影响

星空的日常博客,希望日常能给你帮助 1302

java——关于定义的变量作为参数传递后原变量是否会被更改

关于方法中的参数,看到过这样一句话:被传递进去参数永远都只是副本,不论副本经过了再怎样的变化,只要不接收,原件永远都不会发生改变。最近看到了几道题目刷新了我对这句话的认识:这句话是不对的,或者说是不完全对的。 对于传递的基本数据类型(int 、byte等)来说,传递的参数的确像是副本一样,对原件没什么影响,但是如果传入的参数是原件的地址,那在传入参数的方法中改变的就是地址中的数据,也就是说,原件...

清杉夫人 1201

java bigint 传到前端值莫名其妙变了

直接上解决办法,增加一个配置文件,全局处理,这个方法解决了我的问题。网上还有一些解决方案是对对应的字段增加格式转换配置,工作量比较大。

山顶听风的博客 309

Java序列化JSON时long型数值不准确

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33692284的博客 392

Java 形参数组的值在方法中被修改,实参数组的值也会改变

为什么Java中一旦作为形参的数组的值在方法中被修改,即使没被返回,实参数组的值也会改变?解答。。。

Regino的博客 4505

Java根据不同的业务使用不同的service实现

可以根据不同的业务需求使用不同的service实现来提供相应的服务。通过使用不同的service实现,可以根据具体的业务逻辑和需求来实现相应的服务。

Java技术实践 1225

java接口变化_Java8 在接口的变化

Java8 对接口的改变1.增加了default方法和static方法,这两种方法完全可以有方法体2.default方法属于实例,static方法属于类(接口)3.接口中的静态方法不会被继承,接口中的静态变量会被继承实例如下:package com.xxf.lambda.java8features;/*** com.xxf.lambda.java8features* 2018/9/19* auth...

weixin_36081677的博客 289

微服务下,方法调用传值后参数值发生改变的问题

微服务下,controller调用service的接口,发现从controller中传递过去的id,到了service层变成了别的值,导致项目总是报错解决办法,发现两个项目采用的不是同一个环境下运行的,一个是local环境,一个是dev环境,将其调整一致,ok!...

zuixiaoyao_001的博客 1859

Java中参数传递问题总结

1.问题说明        在C++中,函数调用时有传值调用和传址调用两种方式,但在Java中只有传值调用一种方式。Java中的方法参数为那几种基本数据类型的情况跟C++中一样,传入的只是变量的拷贝。而当参数类型为类对象时,则有可能会误以为是传址调用。    在Java的方法调用中,方法中的参数是以传值的形式进行的,不管它是什么数据类型。如果是基本数据类型,则就是传入该值的一个拷贝;如

qq1169091731的博客 464
上一篇: MySQL explain常见场景分析
下一篇: 细说ConcurrentHashMap计数规则
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值