Java 更改方法中的数组更改外部的数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21653048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:53:31  来源:igfitidea点击:

Changing array in method changes array outside

javavariablesscope

提问by purblue

I have trouble with scope of variable.

我在变量范围方面遇到问题。

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;
}

I expected the output to 1 2 3, but the result was 5 2 3. Why I changed the value in the array in the method, but the original array changed?

我期望输出为1 2 3,但结果为5 2 3。为什么我在方法中改变了数组中的值,但原来的数组改变了?

采纳答案by Brian Roach

An array in Java is an object. When you create an array via new, it's created on the heap and a reference value (analogous to a pointer in C) is returned and assigned to your variable.

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

In C, this would be expressed as:

在 C 中,这将表示为:

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

When you pass that variable to a method, you're passing the reference value which is assigned (copied) to the local (stack) variable in the method. The contents of the array aren't being copied, only the reference value. Again, just like passing a pointer to a function in C.

当您将该变量传递给方法时,您将传递分配(复制)到该方法中的本地(堆栈)变量的引用值。不会复制数组的内容,只会复制引用值。同样,就像在 C 中传递一个指向函数的指针一样。

So, when you modify the array in your method via that reference, you're modifying the single array object that exists on the heap.

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

You commented that you made a "copy" of the array via int[] temp=test... again, this only makes a copy of the reference value (pointer) that points to the single array in memory. You now have three variables all holding the same reference to the same array (one in your main(), two in your method).

您评论说您通过int[] temp=test...再次制作了数组的“副本” ,这只会制作指向内存中单个数组的参考值(指针)的副本。您现在拥有三个变量,它们都持有对同一数组的相同引用(一个在您的 中main(),两个在您的方法中)。

If you want to make a copy of the array's contents, Java provides a static method in the Arraysclass:

如果要复制数组的内容,JavaArrays类中提供了一个静态方法

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

This allocates a new array object on the heap (of the size specified by the second argument), copies the contents of your existing array to it, then returns the reference to that new array to you.

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

回答by SnakeDoc

Definitions:

定义:

  • Reference = A variable that points to the location in memory where your array lives.
  • Value of a Reference = The actual memory address location itself
  • 引用 = 指向数组所在内存位置的变量。
  • 引用值 = 实际内存地址位置本身

You passed the value of the reference of your array into your test()method. Since java is Pass By Value, it passes the value of the reference, not the value of your array (ie. a copy).

您将数组引用的值传递到您的test()方法中。由于 java 是按值传递,它传递引用的值,而不是数组的值(即副本)。

It may be easier to think of a reference as a pointer if you have a C background. So a value of a reference is essentially it's memory address (I'm fudging java rules here but it may be simplest to think of it this way)

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

So, in your example, you pass the value of the reference which points to your array, into your test()method, which then uses that reference value to lookup where your array is in memory, so it can access data in your array.

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

Since in your test()method you do not change your array's reference (where it points to, ie. test = new int[10];), then your test()method acts on the original data in the array (because it still points to your original array's location), leading to element 0being set to a value of 5.

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