当前位置: 首页 > news >正文

Java传递对象是值传递还是引用传递?

🎉 前言

之前一直以为Java传对象是引用传递,直到最近用Java写数据结构链表时遇到一些问题,这才让我重新思考这个问题,经过我的一番研究,发现不能一棒子打死,其实这其中既有值传递,又有引用传递,让我们往下看。

🎉 引用传递的情况

之前一直认为是引用传递,是因为我的使用场景大多数是修改对象的属性,就像下面这段代码:

class LinkNode{int val;LinkNode next;LinkNode(){}LinkNode(int val,LinkNode next){this.val = val;this.next = next;}
}class Main{public static void main(String[] args) {LinkNode L = new LinkNode(666,null);System.out.println("传参之前,L.val="+L.val);Fun(L);System.out.println("传参之后,L.val="+L.val);}static void Fun(LinkNode L){L.val = 999;}
}

在这里插入图片描述
像这样在一个函数的参数列表中传入一个对象,并且在函数内部修改传入对象的属性,会发现在函数外部的对象属性也发生了变化,这就是典型的引用传递。

🎉 值传递的情况

class LinkNode{int val;LinkNode next;LinkNode(){}LinkNode(int val,LinkNode next){this.val = val;this.next = next;}
}class Main{public static void main(String[] args) {LinkNode L = new LinkNode(666,null);System.out.println("传参之前,L.val="+L.val);Fun(L);System.out.println("传参之后,L.val="+L.val);/* 新增代码 */Fun2(L);System.out.println("传参之后,L.val="+L.val);}static void Fun(LinkNode L){L.val = 999;}/* 新增代码 */static void Fun2(LinkNode L){LinkNode l = new LinkNode(111,null);L = l;}
}

这段代码在原先代码的基础上,增添了Fun2()函数,代码中也注释了新增的部分,此时如果我们沿用之前的观点,认为传对象是引用传递,那么在 Fun2(L) 函数内部,L = l;这条语句将对象L的引用更改了,那么在函数外部的L的引用应该也要更改,那么此时打印 L.val应该是111才对,但是实际运行结果如图:
在这里插入图片描述
可见引用的修改只在函数内部成立,在外部不成立,要想修改函数外部L的引用,必须在函数内部手动返回L,并将其赋值给函数外的L,着不就是妥妥的值传递吗?

🎉 解释

先说结论,传对象就是“值传递”。

其实要解释“引用传递“的假象也很简单,我们传入对象实际上传的是对象的引用的副本,也就是值传递,但是这个副本和原对象指向的同一个内存空间,因此,借助副本修改对象的属性和使用原对象修改对象的属性是完全等效的,因为操作的是同一个内存空间。

但是如果我们在函数内部直接对对象的副本进行赋值,就不会影响原对象,因为二者的内存空间不是同一个。

由此可见,对象虽然是引用数据类型,但是传入函数中依然是值传递,因此我们要明确在函数内部操作的内存空间和函数外对应的内存空间是不是一致的,只有一致的情况下,在函数内的修改才会影响函数外,否则不影响。

http://www.lryc.cn/news/461894.html

相关文章:

  • 解锁C++多态的魔力:灵活与高效的编码艺术(上)
  • k8s系列-Rancher 上操作的k8s容器网络配置总结
  • 2024年【氯化工艺】考试题库及氯化工艺考试内容
  • 从commit校验失效问题探究husky原理
  • Azure OpenAI 服务上线具有音频和语音功能的 GPT-4o-Realtime-Preview,免费申请试用
  • 基于IMX6UL的EPIT的定时器实验
  • FreeMarker模板引擎入门:从基础到实践的全面指南
  • YOLOv8模型改进 第十讲 添加全维度动态卷积(Omni-dimensional Dynamic Convolution,ODConv)
  • 【环境搭建】远程服务器搭建ElasticSearch
  • 机器学习与神经网络:诺贝尔物理学奖的新篇章
  • 倍福TwinCAT程序中遇到的bug
  • R语言实现logistic回归曲线绘制
  • 零宽字符(ZWSP)
  • 作业 定时发送邮件
  • 【排序】——2.快速排序法(含优化)
  • AnaTraf | 网络分析系统:高效IT运维工具
  • 踩坑日记:线上接口超时问题排查
  • C语言中的段错误(Segmentation Fault):底层原理及解决方法
  • 1.两数之和 暴力枚举和暴力搜索法
  • 你的收入达到了缴纳个人所得税的标准了吗?
  • 【C++贪心】2086. 喂食仓鼠的最小食物桶数|1622
  • notepad++中实现代码整体缩进和退格
  • 如何调整配置请款单上的立账条件
  • 骨传导耳机精选:2024最佳骨传导耳机有哪些?分享骨传导耳机top5
  • for循环与webAPI练习题
  • FLUX | 轻松掌握FLUX.1 LoRA本地训练秘籍!
  • LeetCode 每日一题 最小元素和最大元素的最小平均值
  • PHP学习记录-编辑器推荐和本地环境的安装
  • 嵌套div导致子区域margin失效问题解决
  • 搭建app业务的服务器优势类型用途等