Java中所有参数均为值传递:基本类型传数值副本,引用类型传地址副本;改对象内容有效,换引用无效;二维数组需分层理解地址,void方法需手动赋值实现“原地”效果。

Java 中所有参数都是值传递,理解这一点是写出健壮方法的关键。不是“看起来像引用就能改一切”,而是要清楚:你传进去的永远是一个副本——基本类型是数值副本,引用类型是地址副本。健壮的方法不依赖“意外修改”,而靠明确的意图和可控的副作用。
明确区分“改内容”和“换引用”
这是最常踩坑的地方。方法里对参数的操作,效果完全取决于你动的是堆里的对象,还是栈里的变量本身:
-
改内容有效:比如
arr[i] = 5、list.add(x)、obj.setName("a")——这些操作通过地址找到原始对象并修改其状态,调用方可见 -
换引用无效:比如
arr = new int[]{1,2}、list = new ArrayList()、obj = new Person()——这只是让形参指向新对象,原变量仍指向旧地址,调用方无感知
数组作为参数时,按“一层一层看地址”来思考
数组是对象,它的变量存的是堆中数组对象的地址;二维数组的外层数组也一样,它存的是“每行引用”的地址:
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
-
nums[0] = 9→ 改的是原数组第 0 个元素,生效 -
nums = new int[]{}→ 形参换地址,原数组不变 -
matrix[0] = new int[]{1,2}→ 替换第 0 行引用,原 matrix 的第 0 行会变(因为外层数组里存的就是这个引用) -
matrix = new int[3][3]→ 只改形参,原 matrix 不受影响
避免假性“返回”:void 方法里真想换数组,得手动拷贝回去
如果算法逻辑必须新建数组(如反转、归并、旋转),又要求 void 方法原地生效,不能靠 return,那就不能写 nums = newArr——这行代码在 void 方法里等于没写:
- 用循环逐个赋值:
for (int i = 0; i - 更高效用系统方法:
System.arraycopy(newArr, 0, nums, 0, newArr.length); - 注意边界:确保
newArr.length ,否则会越界
String 和不可变对象要特别小心
String 是引用类型,但它是不可变的。所有看似“修改”的操作(如 str.concat()、str.toUpperCase())都返回新对象,原引用不会变:
-
str = str + "x"→ 形参指向新字符串,实参 str 还是原来的 - 若需改变外部字符串,要么返回新值(推荐),要么用 StringBuilder 传入并在内部
setLength(0).append(...) - 集合类同理:传
ArrayList可以add/remove,但list = new ArrayList()无效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










