数组似乎是通过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中,则movePiececurrentState值(内存位置) – 引用按值传递。 但是现在movePiece中的currentState MiniMaxBaseCasecurrentState相同的内存位置。 所以现在两个变量都指向同一个数组,即净效应是数组有效地通过引用传递。


编辑:复制多维数组

有些人建议直接使用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并指向原始数组,无论是对象还是嵌套数组。