java所有参数传递都是值传递,包括对象;传入的是引用变量的副本(地址值),基本类型传值本身,对象类型传引用的值,故方法内重新赋值不影响实参,但修改对象内容会影响。

Java里传的是值还是引用?先说结论
Java所有参数传递都是值传递,包括对象。所谓“引用传递”是常见误解——你传进方法的,永远是那个引用变量的副本,不是对象本身,也不是引用的地址。
String 和 StringBuilder 传参表现为啥差这么多?
因为不可变性差异导致行为错觉不同:String 是不可变类,方法内重新赋值 s = "new" 只改了副本指向;StringBuilder 是可变类,调用 append() 会修改堆上原对象内容。
-
String 方法内 s = "abc" 不影响外部变量
-
StringBuilder 方法内 sb.append("x") 会影响外部变量(因操作的是同一堆对象)
- 但若在方法内写
sb = new StringBuilder("y"),外部仍指向原对象——这再次印证:传的是引用的值(即地址副本),不是引用本身
基本类型和对象类型在栈/堆上的实际布局
基本类型(如 int、boolean)的形参直接复制值,存在栈帧里;对象类型(如 List、自定义类)的形参复制的是堆中对象的引用值(一个 4 或 8 字节的地址数值),也存在栈帧里。
- 实参是
int x = 5 → 形参得到独立的 5,改它不影响 x
- 实参是
ArrayList<string> list = new ArrayList()</string> → 形参得到一个跟 list 相同值的引用(指向同一块堆内存),所以能通过它修改集合内容
- 但形参自己被重新赋值(如
list = new ArrayList())不会改变实参变量的指向
为什么 swap(a, b) 在 Java 里永远无效?
因为交换操作需要修改变量本身的指向,而 Java 没有指针或引用类型参数,无法让方法内操作反向影响调用方的栈变量。
- 写
void swap(int a, int b) { int t = a; a = b; b = t; }:只交换了形参副本,对实参无任何影响
- 尝试用数组或包装类(如
AtomicInteger)模拟“引用效果”,本质仍是靠它们内部可变状态,不是语言层面支持引用传递
- 真正需要交换两个变量?只能在调用方代码里写
int t = a; a = b; b = t;
String 和 StringBuilder 传参表现为啥差这么多?
因为不可变性差异导致行为错觉不同:String 是不可变类,方法内重新赋值 s = "new" 只改了副本指向;StringBuilder 是可变类,调用 append() 会修改堆上原对象内容。
-
String方法内s = "abc"不影响外部变量 -
StringBuilder方法内sb.append("x")会影响外部变量(因操作的是同一堆对象) - 但若在方法内写
sb = new StringBuilder("y"),外部仍指向原对象——这再次印证:传的是引用的值(即地址副本),不是引用本身
基本类型和对象类型在栈/堆上的实际布局
基本类型(如 int、boolean)的形参直接复制值,存在栈帧里;对象类型(如 List、自定义类)的形参复制的是堆中对象的引用值(一个 4 或 8 字节的地址数值),也存在栈帧里。
- 实参是
int x = 5 → 形参得到独立的 5,改它不影响 x
- 实参是
ArrayList<string> list = new ArrayList()</string> → 形参得到一个跟 list 相同值的引用(指向同一块堆内存),所以能通过它修改集合内容
- 但形参自己被重新赋值(如
list = new ArrayList())不会改变实参变量的指向
为什么 swap(a, b) 在 Java 里永远无效?
因为交换操作需要修改变量本身的指向,而 Java 没有指针或引用类型参数,无法让方法内操作反向影响调用方的栈变量。
- 写
void swap(int a, int b) { int t = a; a = b; b = t; }:只交换了形参副本,对实参无任何影响
- 尝试用数组或包装类(如
AtomicInteger)模拟“引用效果”,本质仍是靠它们内部可变状态,不是语言层面支持引用传递
- 真正需要交换两个变量?只能在调用方代码里写
int t = a; a = b; b = t;
int x = 5 → 形参得到独立的 5,改它不影响 x
ArrayList<string> list = new ArrayList()</string> → 形参得到一个跟 list 相同值的引用(指向同一块堆内存),所以能通过它修改集合内容list = new ArrayList())不会改变实参变量的指向swap(a, b) 在 Java 里永远无效?
因为交换操作需要修改变量本身的指向,而 Java 没有指针或引用类型参数,无法让方法内操作反向影响调用方的栈变量。
- 写
void swap(int a, int b) { int t = a; a = b; b = t; }:只交换了形参副本,对实参无任何影响 - 尝试用数组或包装类(如
AtomicInteger)模拟“引用效果”,本质仍是靠它们内部可变状态,不是语言层面支持引用传递 - 真正需要交换两个变量?只能在调用方代码里写
int t = a; a = b; b = t;
真正容易被忽略的是:很多人调试时看到对象内容变了,就以为“传的是引用”,却没注意如果在方法里做了 = 赋值,这个动作就彻底断开了和原始变量的关联。









