更改方法中的数组会更改之外的数组

我的变量范围有问题。

public static void main(String[] args){ int[] test={1,2,3}; test(test); System.out.println(test[0]+" "+test[1]+" "+test[2]); } static void test(int[] test){ test[0]=5; } 

我预计输出为1 2 3 ,但结果为5 2 3 。 为什么我在方法中更改了数组中的值,但原始数组发生了变化?

Java中的数组是一个对象。 当您通过new创建数组时,它将在堆上创建,并返回一个引用值(类似于C中的指针)并将其分配给您的变量。

在C中,这将表示为:

 int *array = malloc(10 * sizeof(int)); 

将该变量传递给方法时,您将传递的参考值(已复制)传递给方法中的本地(堆栈)变量。 不复制数组的内容,只复制参考值。 再次,就像将指针传递给C中的函数一样。

因此,当您通过该引用修改方法中的数组时,您将修改堆上存在的单个数组对象。

您评论说,您通过int[] temp=test …再次对数组进行了“复制”,这只会生成指向内存中单个数组的引用值(指针)的副本。 你现在有三个变量都对同一个数组保持相同的引用(一个在你的main() ,两个在你的方法中)。

如果要复制数组的内容,Java会在Arrays类中提供一个静态方法 :

 int[] newArray = Arrays.copyOf(test, test.length); 

这将在堆上分配一个新的数组对象(由第二个参数指定的大小),将现有数组的内容复制到它,然后返回对该新数组的引用。

定义:

  • Reference =一个变量,指向数组所在的内存中的位置。
  • Reference的值=实际的内存地址位置本身

您将数组引用的值传递给test()方法。 由于java是Pass By Value,它传递引用的值,而不是数组的值(即副本)。

如果您有C背景,可能更容易将引用视为指针。 所以引用的值本质上是它的内存地址(我在这里捏造java规则,但这样思考它可能是最简单的)

因此,在您的示例中,将指向数组的引用值传递给test()方法,然后该方法使用该引用值查找数组在内存中的位置,以便它可以访问数组中的数据。

因为在你的test()方法中你没有改变你的数组的引用(它指向的位置,即test = new int[10]; ),那么你的test()方法会对数组中的原始数据起作用(因为它仍然指向原始数组的位置),导致元素0设置为值5