java中对象参数传递是值传递,传的是引用的副本;可修改对象状态但不能改变原变量引用指向。

Java 中对象作为参数传递时,不能改变原变量的引用指向,但可以修改原对象的状态。关键在于:传的是引用的副本,不是引用本身,也不是对象本身。
传的是“地址的副本”,不是“地址本身”
当你写 Person p = new Person("Alice"),变量 p 存储的是堆中对象的内存地址。调用方法时,JVM 把这个地址值复制一份传进去——形参拿到的是一个“一模一样的地址”,两个变量(实参和形参)初始都指向同一块堆内存。
- ✅ 修改对象属性(如
p.setName("Bob")):操作的是堆中同一个对象,原对象内容立刻可见变化 - ❌ 重赋值形参(如
p = new Person("Charlie")):只是让形参指向新地址,原变量p仍牢牢指着旧对象,不受影响
常见误判场景:StringBuffer 和 Map.Entry
比如用 StringBuffer 调用 append(),内容变了,是因为调用了对象方法修改了内部字符数组;但若在方法里写 sb = new StringBuffer("Hi"),外面的 sb 还是原来的实例,不会变。
同理,Map.Entry<k></k> 是个接口,传入后调用 setValue() 会生效(改状态),但 entry = new AbstractMap.SimpleEntry(...) 不会更新外部变量所持的引用。
想真正“换掉原对象”,得靠返回或容器
Java 没有引用传递,但有实用替代方案:
- 让方法返回新对象,由调用方显式重新赋值:
person = updatePerson(person) - 传数组或 Holder 包装类:
Person[] holder = {p},然后在方法内写holder[0] = new Person(...) - 用
Optional或 Builder 表达可变意图,提升代码语义清晰度
一句话总结
Java 所有参数都是值传递;对象参数传的是引用值的副本——副本能开门进屋修东西(改字段),但换不了门牌号(改引用指向)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











