两个对象引用指向同一堆内存地址意味着它们共享同一对象数据,即“一个对象、两个名字”;引用变量存地址而非对象本身,赋值u2 = u1仅复制地址,修改对象状态会同步体现,而重新赋值引用则断开关联。

两个对象引用指向同一个堆内存地址,意思是它们共享同一块实际对象数据——不是“长得一样”,而是“根本就是同一个东西”。Java里没有真正的“两个对象”,只有“一个对象、两个名字”。
引用变量只存地址,不存对象本身
声明 User u1 = new User(); 时,u1 这个变量本身在栈中,里面只放了一个数值(类似门牌号),这个数值指向堆中某块真实内存;new User() 才真正在堆里开辟空间、创建对象。后续写 User u2 = u1;,只是把那个门牌号复制了一份给 u2,两者指向的位置完全相同。
修改一个,另一个立刻可见变化
因为操作的不是副本,而是同一块内存:
-
u1.setName("Alice");→ 堆中那个对象的名字字段被改了 -
System.out.println(u2.getName());→ 输出也是 "Alice" - 哪怕字段是
int age或String email,只要没重新赋值引用,都同步生效
区分“改对象”和“换引用”
关键看操作的是对象内容,还是引用变量本身:
立即学习“Java免费学习笔记(深入)”;
-
u2.setAge(25);→ 改的是堆中对象,u1.getAge()也变成 25 -
u2 = new User();→u2现在指向新地址,u1还指着原来的对象,互不影响 -
u2 = null;→ 只断开u2的连接,u1仍有效,对象不会被回收
怎么验证它们真指向同一地址
不能直接打印内存地址,但有可靠方式:
- 用
==比较:如果u1 == u2返回true,说明是同一对象 - 观察状态同步:改一个的字段,另一个读出来一致,基本可确认
-
System.identityHashCode(obj)在未重写时通常反映底层地址逻辑,相同值是强提示(但不是绝对证据)


















