数组似乎在Java中通过引用传递,这怎么可能?

2022-09-03 09:33:08

如果需要,我可以发布更多代码,但在此之前,我只想问一个关于以下方法的一般问题,其中传递一个数组,然后设置为另一个数组,但由于某种原因,原始数组,即传入的数组,也正在被更改,这如何可能/我该怎么办?谢谢

tempBoard 是一个与 currentState 大小相同的数组,temp[k] 包含在 movePiece 中所做的更改,current 状态在方法中声明,而不是全局变量

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

答案 1

在爪哇:

  • 方法参数确实是按值传递的,但是
  • Java 中的所有对象和数组变量都是引用变量

按值传递引用变量的净效应是,该引用变量所指向的对象或数组是按引用传递的

您的数组实际上是通过引用传递的 - 它是相同的数组。

具体来说,in 是对数组的引用 - 它的值是数组的内存位置。 in 按值传递给 ,因此 in(内存位置)的值如果复制到参数中 - 引用按值传递。但现在 in 指向 与 中的相同内存位置。所以现在这两个变量都指向同一个数组,即净效应是数组有效地通过引用传递。currentStateMiniMaxBaseCasecurrentStateMiniMaxBaseCasemovePiececurrentStateMiniMaxBaseCasecurrentStatemovePiececurrentStatemovePiececurrentStateMiniMaxBaseCase


编辑:复制多维数组

有些人一直建议使用或直接使用,而不遍历到第一个维度/索引。这是行不通的。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中,二维数组实际上是指向(分散的)一维数组集合的指针/引用的数组,即指向一堆(分散的)的指针数组。只需在二维数组上执行 or,只需将指针复制到分散的 int[] 数组,即此浅副本最终共享底层数组集。您必须执行深层复制,如上面的代码所示。int[][]int[]System.arraycopy()Arrays.copyOf()

一些参考:

如何在Java中做2d数组的深度复制?

是的,您应该迭代 2D 布尔数组以对其进行深度复制。

http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
如何复制多维数组?

...但是,复制二维数组的问题更大,因为多维数组表示为数组的数组。这是克隆阵列时的问题。System.arraycopy() 将为您提供对嵌入式数组的引用的副本。...


答案 2

在Java中,没有通过引用传递这样的东西。你似乎知道这一点,并想知道为什么它仍然感觉像是这里发生的事情......

问题是,数组是对象。对象实际上是指针。因此,您将获得指向数组的指针的副本,但它仍然是它所指向的数组。

如果要在对数组进行任何更改之前创建数组的副本,请使用 System.arraycopy()。