java参数传递只有值传递:基本类型传数据副本,引用类型传地址值副本;形参改属性影响实参对象,重赋值不影响实参变量。

Java 中参数传递只有值传递,这是笔试高频踩坑点。很多同学看到对象属性被修改了,就误以为是“引用传递”,结果在判断题、代码填空或执行结果分析中失分。关键不是记结论,而是理解“传的是什么值”——基本类型传数据本身,引用类型传的是地址值的副本。
看清形参改的是“值”还是“值指向的对象”
形参拿到的永远是实参的一个副本。区别在于:基本类型副本是独立数字;引用类型副本是独立的地址值,但这个地址指向堆里同一个对象。
- 对基本类型形参重新赋值(如 a = 5),不影响实参,因为副本和原件互不相干
- 对引用类型形参调用方法修改对象属性(如 p.name = "Tom"),会影响实参对象,因为副本地址和原件地址指向同一块堆内存
- 对引用类型形参重新赋值(如 p = new Person()),只改变副本的地址指向,原件变量仍指向原对象,不会影响实参
遇到数组、集合、StringBuffer 等典型引用类型要特别留心
它们都是引用类型,传参逻辑一致:地址值的副本被传入。但要注意不可变性带来的干扰项。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 数组:a[0] = 100 会改变原数组内容;a = new int[]{1,2} 不会影响原数组变量
- ArrayList:list.add("x") 会反映到原 list;list = new ArrayList() 是局部重定向,无外部影响
- String:虽然也是引用类型,但它是不可变的。所有“修改”操作(如 s.concat())都返回新对象,原变量不变——这点常被拿来设陷阱
画两行内存草图,三秒定位问题本质
笔试时间紧,靠死记容易混淆。遇到传参题,快速画两行:
- 第一行写实参:比如 Person p1 = new Person(); p1.name = "A" → 栈中 p1 存地址,堆中有个 Person 实例
- 第二行写形参:方法内 void f(Person p) → 栈中新变量 p,值等于 p1 的地址(副本),也指向堆中那个 Person
- 然后看代码动了哪部分:改 p.name?→ 堆中对象变了;改 p = new Person()?→ 只动了第二行的 p,第一行 p1 毫不动摇
警惕 Integer、String 等包装类和字符串的“假修改”
它们表面是引用类型,行为却像基本类型——因为不可变。笔试最爱考 Integer i = 128; modify(i); 后 i 是否变化,或者 s += "b" 是否影响原字符串。
- Integer 在 -128~127 范围内有缓存,== 可能为 true,但超出范围或用 new 就不是同一对象
- String 所有拼接、替换操作都生成新对象,原变量引用不变(除非显式重新赋值)
- 真正要“改值”,得用 StringBuilder 或可变容器,否则都是假象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










