java中对象引用传递本质是值传递,传递的是对象地址的副本;变量存储的是堆内存地址而非对象本身,参数传递时复制该地址,修改对象属性会影响原对象,但重新赋值引用不影响原变量。

Java 中对象引用的传递,本质仍是值传递——传递的是“引用的值”,也就是对象在堆内存中的地址副本。
对象变量存的不是对象,而是地址
声明一个对象变量(如 Person p = new Person())时,变量 p 本身并不存储对象数据,它只保存对象在堆内存中的地址(比如 0x7f8a12)。这个地址就是一个具体的数值,和 int 变量存的 10 一样,属于“可被复制的值”。
传参时复制的是这个地址,不是对象本身
当把 p 传给方法时,Java 做的不是“把对象交给方法”,而是把 p 当前存的地址值(如 0x7f8a12)复制一份,赋给形参变量(如 Person q)。此时:
- p 和 q 是两个独立变量,位于不同栈帧中
- 它们的值相同(都是 0x7f8a12),因此指向堆中同一个对象
- 通过 q.name = "Bob" 修改属性,实际是用该地址找到对象并改其内容——原对象被改了,所以 p.name 也变
- 但若在方法内写 q = new Person(),只是让 q 指向新地址,p 仍指向原地址,不受影响
和基本类型传递逻辑一致,只是“值”的含义不同
对比来看:
- 传 int x = 5 → 复制数值 5 给形参,改形参不影响 x
- 传 Person p → 复制地址值 0x7f8a12 给形参,改形参所指对象的属性,会影响原对象;但改形参本身(重赋值),不影响 p
区别不在“传什么”,而在于“这个值代表什么”:基本类型值就是数据本身,引用类型值是通往数据的路径。
数组、集合、StringBuffer 等同理
它们都属于引用类型,传递机制完全相同:
- 传 int[] arr → 复制数组对象的地址
- 执行 arr[0] = 99 → 修改堆中数组元素,原数组可见变化
- 执行 arr = new int[]{1,2} → 只改变形参指向,原变量不变
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











