Java - 数组被无故更改

Java - array is being changed for no reason

我有这个程序,它接受一个二维字母数组,并将它们打乱。但是,我的一行代码无缘无故地更改了一个单独的数组?!

代码如下:

private String[][] words = {{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"}};


public Scramble()
{
    String[] a = words[2];
    // At this point, a = {"g", "h", "i"}
    words[2][0] = words[0][2];
    // After this line, a changes to {"c", "h", "i"}
    words[1][2] = words[2][1];
    words[2] = words[1];
    words[1] = a;
}

为什么要这样做?!

与所有 Java 对象(与 Java 基元相反)一样,数组是引用对象。当你这样做时

String[] a = words[2];

a 成为 words[2] 的内容数组的别名。您对 a 所做的任何更改都会同时发生在 words[2] 上,反之亦然,因为只有一个数组对象从两个地方引用。

当你做这个作业时

words[2][0] = words[0][2];

你从[0][2]中取出一个词(即"c")并将其复制到数组words[2]中代替"g",这也是数组a。因此,您观察到 a 内容的变化。

如果您不希望在对 words[2] 进行更改时更改 a,请复制而不是简单地分配数组:

String[] a = Arrays.copyOf(words[2]);

我相信您对 java 数组的按值赋值与其他语言中的按引用赋值的工作方式相似感到困惑。他们的工作方式是在分配过程中

String[] a = words[2];

您确实在初始化一个新的字符串数组 a 并将其设置为等于变量 words[2] 存储的值。但是数组变量存储地址,因此String[] a准备从存储在words[2]中的地址中取出一个地址(引用)。以这种方式,它们指向内存中相同的 space,即一维数组 [g, h, i]

当您更改 words[2] 并在 a 中看到相同的更改时,这是因为写入数组只会改变指向的内存 space,而不是指针. awords[2] 将始终具有相同的值。