Java引用类型赋值是地址值的复制传递,本质仍为值传递;变量存储的是指向堆中对象的地址而非对象本身,赋值仅复制地址,故p和p1指向同一对象,但重赋值时互不影响。

引用类型赋值不是“地址传递”,而是地址值的复制传递——它本质仍是值传递,只不过传递的内容是内存地址。
引用变量存的不是对象,是地址
声明一个引用类型变量,比如 Person p = new Person(),变量 p 本身不存姓名、年龄等数据,只存类似 0x7f8a12b4 这样的十六进制地址。这个地址指向堆内存中真正存放对象数据的位置。
就像你家的门牌号不是房子,只是找到房子的线索;p 是“标签”,对象本体在堆里。
赋值操作复制的是地址,不是对象内容
执行 Person p1 = p 时:
- 不会把整个 Person 对象复制一份
- 只是把 p 当前持有的地址(比如 0x7f8a12b4)拷贝给 p1
- 结果是 p 和 p1 都指向堆中同一个对象
为什么看起来像“地址传递”?
因为两个变量共享同一块堆内存,所以:
- 修改 p1.name = "Alice",p.name 也会变成 "Alice"
- 调用 p1.list.add("item"),p.list 里同样多出一项
这种“改一个,另一个也变”的现象,容易被误认为是“传了地址本身”,其实是双方都拿着相同的地址副本,自然访问到同一处数据。
关键区别:重赋值不影响对方
如果后续写 p1 = new Person():
- p1 会拿到一个新地址(比如 0x9e3c56a1),指向新对象
- p 仍持有原来的 0x7f8a12b4,完全不受影响
- 这说明传的不是“地址本身”,而是一个可独立修改的地址副本
真正的地址传递(如 C++ 引用参数)不允许形参脱离实参独立重定向,Java 不支持这种机制。

















