Java所有参数传递都是值传递,基本类型传值副本,引用类型传引用地址副本,方法内重赋值不影响调用方变量,修改对象状态则可见。

Java里所有参数传递都是值传递
Java没有引用传递,连对象也是值传递——只不过这个“值”是对象引用的副本。很多人误以为Object类型参数能直接修改原始引用本身,其实不能。
基本类型参数传的是真实值的副本
传入int、boolean、double等,方法内对形参的任何赋值操作,不影响调用方的原始变量。
public static void modifyInt(int x) {
x = 100;
}
int a = 5;
modifyInt(a);
System.out.println(a); // 输出 5,没变
引用类型参数传的是引用地址的副本
传入String、ArrayList、自定义类实例时,传的是堆中对象地址的拷贝。这意味着:
- 可以在方法内通过该引用调用对象方法、修改其内部状态(比如
list.add())——原对象可见变化 - 但若在方法内让形参指向新对象(如
list = new ArrayList()),调用方的引用不会变 -
String因不可变性,看似“没改”,其实是每次操作都生成新对象,原引用仍指向旧字符串
public static void modifyList(ArrayListlist) { list.add("new"); // ✅ 原list可见 list = new ArrayList<>(); // ❌ 调用方list不受影响 }
想让方法“改变引用本身”?只能靠返回值或包装容器
Java不支持类似C++的&引用参数,也没法让方法直接把新对象地址“写回”调用方变量。常见应对方式:
立即学习“Java免费学习笔记(深入)”;
- 方法返回新对象,由调用方显式重新赋值:
list = replaceList(list) - 用数组长度为1的容器(如
AtomicReference、Object[])包裹引用,传数组本身(仍是值传递,但数组元素可被替换) - 封装成可变容器类,暴露
set()方法
绕开语言限制不是错,但得清楚:这不是“引用传递生效了”,而是你主动用了可变载体。
容易忽略的是,final修饰的形参只是禁止重新赋值,不影响对其所指对象内部状态的修改——这点常和“值传递”机制混淆。









