Java中所有参数传递都是值传递,基本类型传值副本互不影响,引用类型传地址副本可修改对象内容但无法改变原引用指向。

Java 中所有参数传递都是值传递,引用变量也不例外——传的是“地址值的副本”,不是地址本身。理解这点,就能一眼看穿多数参数修改行为背后的逻辑。
基本类型参数:改形参不影响实参
基本类型(如 int、boolean、char)的值直接存在栈中。方法调用时,JVM 把这个值复制一份给形参,两者完全独立。
- 形参在自己栈帧里操作副本,哪怕改成 100,原变量还是原来的值
- 典型表现:方法内赋值、自增、重计算,对外部零影响
- 例如:int x = 5; modify(x); → 方法里 x = 20,调用后外部 x 仍是 5
引用类型参数:副本地址能改对象内容,但不能换对象本身
引用变量本身存的是堆中对象的地址(比如 0x7a8b),这个地址值被复制给了形参。两个变量指向同一块堆内存,所以能协同操作对象内部状态。
- 通过形参修改对象属性(如 person.name = "Tom"),实参看到变化——因为操作的是同一个对象
- 但若在方法内让形参指向新对象(如 p = new Person()),只是改了副本地址,原变量仍指着旧对象
- 关键口诀:同地址改内容,同生效;换地址只换局部,不牵连
String 和包装类:不可变性放大了“值传递”效果
String、Integer、Double 等是不可变类。看似引用类型,但每次“修改”实际都新建对象,原引用根本没动。
- s += "world" 不是改原字符串,而是让形参指向新字符串对象
- 外部实参仍持有旧字符串的地址,自然看不到变化
- 这和“传引用”无关,纯粹是对象不可变 + 值传递双重作用的结果
用调试视角验证:看栈与堆的真实关系
运行时观察栈帧和堆内存,是最直观的辨析方式:
- 在 IDE 中打断点,进入方法后查看形参和实参的内存地址(IDEA 可用 “View as Object” 或打印 System.identityHashCode())
- 你会发现:基本类型地址不同;引用类型形参与实参的 identityHashCode 相同(说明指向同一对象),但变量本身的内存地址不同(说明是两个独立栈变量)
- 一旦执行 p = new Xxx(),再看 identityHashCode 就变了——形参已指向新对象,而实参不变
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











