会改变。因为形参和实参共享同一块堆内存,修改对象成员变量(如p.name="tom")直接影响堆中对象,外部可见;但重新赋值引用(如p=new person())只改变形参指向,不影响实参。

会改变。因为方法内部的形参和外部的实参指向堆内存中同一个对象,修改成员变量就是直接操作那块共享的内存。
形参和实参共享同一块堆内存
Java 中所有变量(包括对象引用)都存放在栈中,而对象本身在堆中。当你把一个对象传入方法时,JVM 把该引用变量所存的地址(比如 0x7a1f)复制一份给形参。此时两个变量——实参和形参——栈中值相同,都指向堆里那个唯一的对象实例。
- 执行 p.name = "Tom":是顺着这个地址找到堆中的对象,把它的
name字段覆盖掉,外部通过原地址读取,自然看到新值 - 执行 p = new Person("Jerry"):只是让形参的栈值变成新地址(如 0x9b3c),实参仍指向旧地址,互不影响
关键看操作目标:改对象内容 vs 改引用本身
是否影响外部,不取决于“是不是对象”,而取决于你动的是什么:
- ✅ 调用
list.add()、sb.append()、user.setAge(25)—— 这些都在修改堆中对象的状态,外部可见 - ❌ 写
list = new ArrayList()、user = new User()—— 只改变了形参这个局部变量的指向,外部引用不变
String 等不可变类是个特例,但机制没变
String 也是引用类型,同样传地址副本。但它内部字段是 final 的,任何“修改”如 str += "x" 实际是创建新字符串并让形参指向它。外部变量仍指着原来的字符串对象,所以看起来“没变”——不是传递方式不同,而是对象自己不允许被就地修改。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











