多数语言中对象传参本质是传递引用的副本:Java值传地址、Python绑定对象、C#区分class/struct、JS引用类型可变但赋值不改外部指向。

对象作为方法参数传递,在大多数面向对象语言中默认是“按引用传递”(实际是传递对象的引用值),不是复制整个对象。关键在于理解底层机制,而不是简单记“传引用”或“传值”。
Java:传递的是对象引用的副本
Java 中没有真正的“引用传递”,而是“值传递”,只不过这个“值”是对象在堆内存中的地址(即引用)。方法内修改对象属性会影响原对象,但重新赋值引用不会改变外部变量指向。
- 修改对象状态(如 obj.setName("Alice"))→ 外部可见
- 重新赋值参数(如 obj = new Person())→ 不影响外部变量
- 基本类型(int、boolean等)始终是值传递,修改不影响外部
Python:变量是对象的标签,传递的是对象本身
Python 中所有变量都是对象的引用(更准确说是“绑定到对象”)。传参本质是把实参绑定的对象,再绑定给形参名。只要对象可变(如 list、dict),方法内修改内容就会影响外部。
- list.append(x) 或 dict["k"] = v → 外部列表/字典同步变化
- param = [1,2](重新赋值)→ 仅改变形参绑定,不影响原变量
- 不可变对象(str、tuple、int)无法原地修改,所以表现像值传递
C#:区分 class 和 struct,支持 ref/out 显式控制
class 类型默认按引用语义传递(传递引用的副本),struct 是值类型,默认复制整个结构体。若需修改实参变量本身(比如换一个对象),可用 ref 或 out 关键字。
- 普通调用:Method(obj) → 可修改 obj 属性,不能让 obj 指向新实例
- 显式引用:Method(ref obj) → 方法内可执行 obj = new MyClass(),外部 obj 被更新
- struct 参数默认复制,大 struct 建议加 ref 避免开销
JavaScript:对象参数天然“可变”,但赋值不改变外部引用
JS 中对象、数组、函数等都是引用类型,传入函数后,形参和实参指向同一堆内存对象。
- obj.name = "Bob" 或 arr.push(4) → 外部对象同步更新
- obj = {id: 2} → 仅让形参指向新对象,实参不变
- 原始类型(string、number、boolean)始终按值传递

















