数组似乎在 Java 中通过引用传递,这怎么可能?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4892992/
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
Array seems to be getting passed by reference in Java, how is this possible?
提问by jbernie2
I can post more code if I need to, but before that I would like to just ask a general question about the following method in which an array is passed, and then set to another array, but for some reason the original array, the one being passed in, is also getting changed, how this possible/what should i do? Thanks
如果需要,我可以发布更多代码,但在此之前我只想问一个关于以下方法的一般问题,其中传递一个数组,然后设置为另一个数组,但由于某种原因,原始数组,那个被传入,也在发生变化,这怎么可能/我该怎么办?谢谢
tempBoard is an array of same size as currentState, and temp[k] contains the changes that are being made in movePiece, current state is declared in the method and is not a global variable
tempBoard 是一个与 currentState 大小相同的数组,temp[k] 包含在 movePiece 中所做的更改,当前状态是在方法中声明的,而不是全局变量
private int[][] MiniMaxBaseCase(int[][] currentState, int currentColor)
{
tempBoard = movePiece(currentState,temp[k]);
}
private int[][] movePiece(int[][] currentState, int[] move)
{
if(move[0] == -1)
return currentState;
//if the piece is just moving
if(move[4] == -1)
{
currentState[move[2]][move[3]] = currentState[move[0]][move[1]];
currentState[move[0]][move[1]] = 0;
return currentState;
}
//if the piece is jumping another
if(move[4] != -1)
{
currentState[move[4]][move[5]] = currentState[move[0]][move[1]];
currentState[move[2]][move[3]] = 0;
currentState[move[0]][move[1]] = 0;
return currentState;
}
return currentState;
}
回答by Bert F
In Java:
在 Java 中:
- method argumentsare indeed passed-by-value, but
- all object and array variablesin Java are reference variables.
- 方法参数确实是按值传递的,但是
- Java 中的所有对象和数组变量都是引用变量。
The net effect of a reference variablebeing passed-by-valueis that the object or array pointed toby that reference variable is passed-by-reference.
一个的净效应参考变量感传递按值是该对象或指向的数组通过引用变量传递按引用。
Your array was effectively passed-by-reference - its the same array.
您的数组实际上是按引用传递的 - 它是同一个数组。
Specifically, currentState
in MiniMaxBaseCase
is a reference to an array - the value of it is the memory location of the array. currentState
in MiniMaxBaseCase
is passed by value to movePiece
, so the value of currentState
in MiniMaxBaseCase
(a memory location) if copied into parameter currentState
in movePiece
- the reference was passed by value. But now currentState
in movePiece
points to the same memory location as currentState
in MiniMaxBaseCase
. So now both variables both point to the same array, i.e. the net effect was that the array was effectively passed-by-reference.
具体来说,currentState
inMiniMaxBaseCase
是对数组的引用 - 它的值是数组的内存位置。 currentState
inMiniMaxBaseCase
是按值传递给 的movePiece
,因此如果将currentState
in MiniMaxBaseCase
(内存位置)的值复制到参数currentState
in movePiece
- 引用是按值传递的。但是,现在 currentState
在movePiece
指向相同的存储单元currentState
中MiniMaxBaseCase
。所以现在两个变量都指向同一个数组,即实际效果是数组有效地通过引用传递。
Edit: Copying multi-dimensional arrays
编辑:复制多维数组
Some people have been suggesting to use System.arraycopy()
or Array.copyOf()
directly without traversing into the first dimension/index. This won't work.
有些人一直在建议使用System.arraycopy()
或Array.copyOf()
直接使用而不遍历第一维/索引。这行不通。
Use this instead:
改用这个:
public static int[][] copyOf(int[][] original) {
int[][] copy = new int[original.length][];
for (int i = 0; i < original.length; i++) {
copy[i] = Arrays.copyOf(original[i]);
}
return copy;
}
The reason a direct copy won't work is because in Java, a 2-dimensional array is really an array of pointers/references to a collection of (scattered) 1-dimensional arrays, i.e., int[][]
is an array of pointers to a bunch of (scattered) int[]
. Simply doing a System.arraycopy()
or Arrays.copyOf()
on a 2-D array will simply copy the pointers to the scattered int[]
arrays, i.e. this shallow copy ends up sharing the underlying set of arrays. You must do a deep copy as shown in the code above.
直接复制不起作用的原因是因为在 Java 中,二维数组实际上是指向(分散的)一维数组集合的指针/引用数组,即,int[][]
是指向一堆指针的数组(分散)int[]
。简单地在二维数组上执行 aSystem.arraycopy()
或Arrays.copyOf()
将简单地复制指向分散int[]
数组的指针,即这个浅拷贝最终共享底层数组集。您必须进行深度复制,如上面的代码所示。
Some references:
一些参考:
How do I do a deep copy of a 2d array in Java?
Yes, you should iterate over 2D boolean array in order to deep copy it.
是的,您应该遍历 2D 布尔数组以对其进行深度复制。
http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
How do I copy multi-dimensional arrays?
http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
如何复制多维数组?
... Copying a two dimensional array is however more problematical because multi-dimensional arrays are represented as arrays of arrays. This is an issue when you are cloning an array. System.arraycopy() will give you a copy of the references to the embedded arrays. ...
... 然而,复制二维数组更成问题,因为多维数组表示为数组的数组。当您克隆阵列时,这是一个问题。System.arraycopy() 将为您提供对嵌入数组的引用的副本。...
回答by yankee
In Java there is NO SUCH THING as pass-by-reference. You seem to know that and wonder why it still feels like that this is what happens here...
在 Java 中,没有像传递引用那样的东西。你似乎知道这一点,并想知道为什么它仍然感觉这就是这里发生的事情......
Well the Problem is, that arrays are Objects. And Objects are actually Pointers. So you get a COPY of the pointer to the array, but it's still the array it is pointing to.
那么问题是,数组是对象。对象实际上是指针。所以你得到了指向数组的指针的副本,但它仍然是它指向的数组。
Use System.arraycopy() if you want to create a copy of the array before making any changes to it.
如果要在对其进行任何更改之前创建数组的副本,请使用 System.arraycopy()。
回答by RichardTheKiwi
Take some time to have a good read of this.
花一些时间好好阅读一下这篇文章。
http://www.cs.toronto.edu/~dianeh/tutorials/params/
http://www.cs.toronto.edu/~dianeh/tutorials/params/
Skip down to "Passing Arrays"
跳到“传递数组”
Arrays are references. This means that when we pass an array as a parameter, we are passing its handle or reference. So, we can change the contents of the array inside the method.
数组是引用。这意味着当我们将数组作为参数传递时,我们传递的是它的句柄或引用。因此,我们可以在方法内部更改数组的内容。
This is from a course "148: Introduction to Computer Science", which should fit around the first 2 lessons on the Java language.
这是一门课程“148:计算机科学概论”的内容,该课程应围绕 Java 语言的前 2 课进行。
To pass a copy of an array to a function, in Java 1.6, you can use Array.copyOf, e.g
要将数组的副本传递给函数,在 Java 1.6 中,您可以使用 Array.copyOf,例如
tempBoard = movePiece(Arrays.copyOf(currentState, currentState.length), temp[k]);
Note:Array.copyOf
is only good for single-dimension array of primitives. Used on anything else, it gives you an independent array, with all elements IDENTICAL and pointing to the original array, be it Objects or nested arrays.
注意:Array.copyOf
仅适用于基元的单维数组。用于其他任何东西,它为您提供一个独立的数组,所有元素都相同并指向原始数组,无论是对象还是嵌套数组。