数组似乎是通过Java引用传递的,这怎么可能?
如果需要,我可以发布更多代码,但在此之前我想问一个关于下面传递数组的方法的一般问题,然后设置为另一个数组,但由于某种原因原始数组,一个被传入,也正在改变,这怎么可能/我该怎么办? 谢谢
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; }
在Java中:
- 方法参数确实是按值传递的 ,但是
- Java中的所有对象和数组变量都是引用变量 。
值为值传递的引用变量的净效果是该引用变量 指向的对象或数组是通过引用传递的 。
您的数组实际上是通过引用传递的 – 它是相同的数组。
具体来说, MiniMaxBaseCase
中的currentState
是对数组的引用 – 它的值是数组的内存位置。 MiniMaxBaseCase
currentState
通过值传递给movePiece
,因此如果复制到movePiece
参数currentState
中,则movePiece
的currentState
值(内存位置) – 引用按值传递。 但是现在movePiece
中的currentState
MiniMaxBaseCase
与currentState
相同的内存位置。 所以现在两个变量都指向同一个数组,即净效应是数组有效地通过引用传递。
编辑:复制多维数组
有些人建议直接使用System.arraycopy()
或Array.copyOf()
而不遍历第一个维度/索引。 这不行。
改为使用它:
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; }
直接复制不起作用的原因是因为在Java中,二维数组实际上是指向(分散的)一维数组集合的指针/引用数组,即int[][]
是一个数组指向一堆(散乱的) int[]
指针。 简单地在二维数组上执行System.arraycopy()
或Arrays.copyOf()
只会将指针复制到分散的int[]
数组 ,即这个浅层副本最终会共享底层数组。 您必须执行深层复制,如上面的代码所示。
一些参考:
如何在Java中对二维数组进行深层复制?
是的,您应该迭代2D布尔数组以进行深度复制。
http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
如何复制多维数组?
然而,复制二维数组更成问题,因为多维数组表示为数组数组。 克隆数组时这是一个问题。 System.arraycopy()将为您提供嵌入式数组的引用的副本。 ...
在Java中,没有任何东西作为传递参考。 你似乎知道这一点,并想知道为什么它仍然感觉这就是这里发生的……
问题是,数组是对象。 而物体实际上是指针。 所以你得到一个指向数组的指针的COPY,但它仍然是它指向的数组。
如果要在对数组进行任何更改之前创建数组的副本,请使用System.arraycopy()。
花点时间仔细阅读一下。
http://www.cs.toronto.edu/~dianeh/tutorials/params/
跳到“传递arrays”
数组是引用。 这意味着当我们将数组作为参数传递时,我们传递其句柄或引用。 因此,我们可以在方法内部更改数组的内容。
这是来自“148:计算机科学概论”的课程,该课程应该适合Java语言的前两课。
要将数组的副本传递给函数,在Java 1.6中,可以使用Array.copyOf,例如
tempBoard = movePiece(Arrays.copyOf(currentState, currentState.length), temp[k]);
注意: Array.copyOf
仅适用于单Array.copyOf
元数组。 在其他任何东西上使用它,它会为你提供一个独立的数组,所有元素都是IDENTICAL并指向原始数组,无论是对象还是嵌套数组。