Java中只有值传递,所谓“引用传递”是误解;本质是传递变量中存储的地址副本,实参与形参各自独立,但初始指向同一堆对象,故可修改对象内容却无法改变实参引用指向。

Java 中只有值传递,这是铁律。所谓“常见误区”,本质是把“传递引用类型的值”误解为“引用传递”。辨析关键不在背结论,而在看清变量、地址、对象三者的关系——变量存地址,地址指对象,方法只拿到地址的副本。
误区一:“对象能被修改,所以是引用传递”
错在混淆了“修改对象内容”和“修改变量本身”。形参拿到的是实参中存储的那个地址的副本,两个变量(实参和形参)各自独立,但初始时指向堆中同一个对象。因此:
- 通过形参修改对象属性(如 obj.name = "new"),堆中对象变了,实参看到的自然也变
- 但若在方法内让形参指向新对象(如 obj = new Person()),只是改了形参这个“盒子”里装的地址,实参盒子里的旧地址毫发无损
误区二:“String 和 Integer 改不了,说明它们特殊”
不是它们特殊,而是它们不可变。String、Integer 等包装类对象一旦创建,内部状态就不能改。所有看似“修改”的操作(如 s += "x" 或 i++),实际都是新建对象并让变量指向它。而形参指向新对象,不影响实参原来指向的旧对象。
这和可变对象(如 ArrayList、自定义 Person 类)形成鲜明对比:后者允许不换地址只改内容,所以外部可见变化。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
立即学习“Java免费学习笔记(深入)”;
误区三:“数组传进去能改元素,所以数组是引用传递”
数组是引用类型,传递的仍是地址副本。你能改 arr[0] = 99,是因为你用副本地址找到了堆里的原数组,再改它的第 0 个槽位;但如果你写 arr = new int[]{1,2},就只是让形参换了个地址,原数组引用没动。这和普通对象行为完全一致,不是数组特例。
一个快速自测法:看“重新赋值”是否影响外部
写一个方法,对参数做两件事:一是改它指向的对象的某个字段,二是让它指向一个全新对象。调用后检查外部变量:
- 字段改了 → 说明对象可变,且地址副本有效(正常)
- 变量本身没换指向 → 说明形参重赋值不影响实参(证实是值传递)
只要这个测试结果成立,你就真正理解了 Java 的参数机制。

















