HOWTO · Java
在 Java 中数组是以值传递还是以引用传递
本文介绍了 Java 中检查数组是按值传递还是按引用传递。
本页内容
Java 对所有方法参数都采用值传递。当参数是数组时,复制到形参中的值是指向数组对象的引用。因此,调用方和形参可以引用同一个对象,但它们仍是两个独立变量。这解释了为什么修改数组元素对调用方可见,而把另一个数组赋给形参却不会影响调用方。
Java 如何传递参数
引用是一种让代码能够访问对象的值;引用本身不是对象。方法接收的是引用值的副本。方法调用开始时,调用方的数组变量和方法形参都引用同一个数组对象。Java 不会按引用传递数组变量本身,因此方法无法通过给自己的形参赋值来替换调用方的变量。
关键区别在于修改对象和修改变量。给数组元素赋值会修改共享对象;给形参赋值只会改变形参中的引用副本。尽管这两种操作都发生在被调用的方法内,它们产生的效果却不同。
修改数组元素会如何影响调用方
方法写入 values[index] 时,会修改两个引用都能访问到的数组对象中的一个元素。方法返回后,调用方也能看到该元素的变化。这里按值传递的是引用;元素修改之所以可见,是因为引用副本仍指向同一个对象。
方法重新赋值数组形参时会发生什么
把一个新数组赋给形参后,形参会改为引用另一个对象。这不会改变调用方的变量;调用方的变量仍引用原来的数组。重新赋值之前对原对象所做的修改,调用方仍能看到,但调用方不会获得形参中的新引用。若要替换调用方的数组变量,可以返回新数组,并在调用处将返回值赋给该变量;也可以直接修改原数组。
基本类型形参的行为
基本类型参数同样按值传递:形参一开始持有基本类型值的副本。如果方法给这个形参赋了另一个数值,调用方的变量不会改变。这与重新给数组形参赋值类似,而不同于修改数组元素。数组的情况多了一层引用:复制得到的引用值可用于修改共享对象,而赋予新引用只会影响局部形参。
运行下面这个完整示例:
本节中的代码以及显示的标签或输出仍为英文。
public class ArrayArgumentDemo {
static void changeFirst(int[] values) {
values[0] = 9;
}
static void replaceParameter(int[] values) {
values = new int[] {7, 8};
}
static void changeNumber(int number) {
number = 9;
}
public static void main(String[] args) {
int[] numbers = {1, 2};
changeFirst(numbers);
System.out.println(numbers[0]);
replaceParameter(numbers);
System.out.println(numbers[0]);
int count = 1;
changeNumber(count);
System.out.println(count);
}
}
9
9
1
第一条打印语句显示元素已经改变。第二条显示,即使方法形参被赋予另一个数组,调用方的数组仍保持不变。最后一条显示调用方的基本类型变量也没有改变。
要点总结
Java 始终按值传递参数,包括数组引用。当调用方和方法形参引用同一个数组对象时,对数组元素的修改会对调用方可见。重新给形参赋值只会改变它的局部引用;给基本类型形参赋值也只会改变它的局部副本。把对象修改与形参赋值区分开,就能准确判断这些操作的影响。