java所有参数都是值传递:基本类型传数值副本,引用类型传地址副本;修改对象内容会影响原对象,但重赋值引用变量不影响原变量。

Java 方法调用中,所有参数都是值传递——这点没有例外。差异只在于“值”本身的内容:基本类型传的是数据本身,对象类型传的是对象地址的副本。理解这一点,就能自然区分两者行为。
基本类型:传的是数值的副本
变量在栈中直接存值(如 int a = 5,栈里就放着数字 5)。调用方法时,这个 5 被复制一份给形参。方法内无论怎么改形参,原变量不受影响。
- 修改形参只是改了副本,原始变量仍保留在原栈位置
- 两个变量互不关联,内存地址不同,生命周期也独立
- 例如交换操作失败,正是因为 swap(int x, int y) 交换的只是副本
对象类型:传的是引用地址的副本
变量(如 List
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 形参和实参的地址副本指向同一个堆对象 → 修改对象内容(如 add、set、setName)会影响外部
- 但若在方法内让形参指向新对象(如 list = new ArrayList()),只改变副本的指向,原变量仍指向旧对象
- String、Integer 等不可变类型也遵循此规则:看似没变,是因为操作触发了新对象创建,原引用未动
关键判断标准:看是否改变了引用本身的指向
只要方法内对参数做了 = 赋值(尤其是 new、null 或其他对象引用),那就只是在改副本的指向,不影响外部。而调用对象的方法(如 obj.setName()、list.add())是在通过地址副本操作堆中同一对象。
- 外部能感知变化 → 操作的是对象内部状态
- 外部无变化 → 操作的是引用副本自身(重赋值、重新指向)
- 一个简单验证方式:在方法末尾打印实参对象的 hashCode(),和外部一致说明指向没变;若内部做了 p = new Person(),hashCode 不影响外部结果
别被“对象可修改”误导成“引用传递”
容易混淆的点在于:对象参数确实能“影响外部”,但这不是因为 Java 支持引用传递,而是因为地址副本和原引用共享同一块堆内存。C++ 中的引用传递(void f(Person& p))允许直接让 p = new Person() 改变外部变量指向,Java 做不到——这正是本质区别。
- Java 只有一种传递机制:值传递
- 所谓“对象传引用”,是口语化误读;准确说法是“传引用的值”
- 设计上更安全:避免方法意外篡改调用方的变量指向
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










