Java中所有方法参数传递都是值传递,基本类型传数值副本,引用类型传地址副本;形参修改基本类型不影响实参,修改引用类型对象属性会影响实参,但重新赋值引用不会影响实参。

Java 中所有方法参数传递都是值传递,没有例外。关键不是“传什么类型”,而是“传什么内容”——基本类型传数值副本,引用类型传地址副本。理解这点,就能预判方法内修改是否影响外部变量。
基本类型:传的是数值本身的一份拷贝
int、double、boolean 等变量的值直接存在栈中。调用方法时,JVM 把这个值复制一份给形参,两者完全独立。
- 形参在自己栈帧里操作,比如把 int 形参从 5 改成 100,外部原始变量仍是 5
- 方法执行完,形参副本随栈帧一起销毁,原始变量不受任何干扰
- 典型例子:
void modify(int x) { x = 42; }调用后实参值不变
引用类型:传的是堆中地址的一份拷贝
Person、ArrayList、String 等变量本身存的是对象在堆中的地址(比如 0x7a8b),这个地址值被复制给了形参。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 实参和形参初始指向同一块堆内存,所以通过形参改对象属性(如
p.name = "Tom"),外部能立刻看到变化 - 但若在方法内让形参指向新对象(如
p = new Person()),只是改了副本的地址,实参仍指着原来的对象 - 这就像你和同事各拿一张同一仓库的门牌号纸条;你按纸条进去贴标签,仓库变了;你涂改自己那张纸条,对方照旧能找到原仓库
不可变类型(String、Integer):地址副本 + 内容不可改 = 表面“改不动”
它们也是引用类型,同样传地址副本。但每次看似“修改”,实际都新建对象并返回新地址。
-
s += "world"不是改原字符串,而是让形参指向新字符串对象 - 外部实参仍持有旧字符串的地址,自然看不到变化
- 这不是“传引用失效”,而是不可变性叠加值传递的自然结果
- 真要可变操作,换用
StringBuilder或StringBuffer
验证方式:看 identityHashCode 和调试栈帧
最直观的办法是运行时观察内存行为:
- 用
System.identityHashCode(obj)打印实参与形参的对象哈希码:相同说明指向同一堆对象 - 在 IDE(如 IDEA)中打断点,进入方法后查看两个变量的内存地址:栈中地址不同,证明是两个独立变量
- 执行
p = new Person()后再查哈希码,形参的变了,实参的保持不变
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










