java中对象传参传递的是引用值的副本,能修改对象内容但不能改变原引用指向;基本类型传参同理,均为值拷贝。

Java 中类与对象作为参数传递时,本质上传递的是引用的副本,不是对象本身,也不是真正的“引用传递”。这种机制直接影响你能否修改原始对象的数据,但不改变原始引用变量所指向的对象地址。
类对象传参传递的是“引用值的副本”
当你写 User user = new User(); 时,user 是一个引用变量,它存的是堆中那个 User 实例的内存地址。调用方法如 modify(user) 时,JVM 把这个地址值复制一份给形参 obj —— 两个变量(user 和 obj)各自在栈中独立存在,但初始时指向堆中同一个对象。
- 这和 int a = 10; f(a); 中把数字 10 复制一份给形参,逻辑完全一致:都是“值”的拷贝
- 区别只在于:基本类型拷贝的是数值本身;引用类型拷贝的是地址值
能改对象内容,但改不了引用指向
因为形参和实参持有相同的地址,它们能访问并修改堆中同一个对象的状态:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- ✅ obj.setName("Tom") → 原始 user.getName() 变为 "Tom"
- ✅ obj.list.add("item") → 原始 user.list 也包含该元素
- ❌ obj = new User() → 仅让形参 obj 指向新对象,user 仍指向原对象
- ❌ obj = null → 形参变为空,对 user 完全无影响
数组、集合、String 等也遵循同一规则
数组是引用类型,所以 int[] arr 传参后:
- ✅ arr[0] = 99 → 原数组首元素被改
- ❌ arr = new int[]{1,2} → 不会影响调用方的原数组变量
String 虽是引用类型,但不可变(immutable)。看似“改了字符串”,其实是创建了新对象并让引用指向它——而这个新指向只发生在形参局部,外部实参仍指向原字符串。
常见误操作与规避建议
容易踩坑的地方往往源于混淆“改对象”和“改引用”:
- 不要指望在方法里 new 一个新对象并赋给形参,就能让外部变量指向它
- 若需替换整个对象,应返回新对象,由调用方显式重新赋值:user = resetUser(user)
- 对集合类(如 ArrayList),避免在方法内直接 clear() 或 add() 后不加说明——虽合法,但属于隐式副作用,建议加注释或封装为明确语义的方法
- 调试时可打印 System.identityHashCode(obj) 对比前后是否相同,快速验证是否仍是同一对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










