我有这个程序,它采用2D字母数组,并加扰它们。但是,我的代码中的一行更改了一个单独的数组,因为没有任何明显的理由?!
以下是代码:
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;
}
为什么要这样做?!
答案 0 :(得分:3)
与所有Java对象(与Java基元相对)一样,数组是引用对象。当你这样做时
String[] a = words[2];
a
成为words[2]
内容数组的别名。您对a
所做的任何更改都会同时发生在words[2]
,反之亦然,因为只有一个数组对象从两个地方引用。
进行此作业时
words[2][0] = words[0][2];
你从[0][2]
(即"c"
)中取词并将其复制到"g"
代替数组words[2]
,这也是数组a
}。因此,您观察到a
内容的更改。
如果您在更改a
时不希望更改words[2]
,请复制而不是简单地分配数组:
String[] a = Arrays.copyOf(words[2]);
答案 1 :(得分:0)
我相信你对java通过数组赋值赋值的方式与其他语言中的引用赋值类似感到困惑。他们的工作方式是在分配
的过程中String[] a = words[2];
您确实正在初始化一个新的字符串数组 a 并将其设置为等于变量 words [2] 存储的值。但数组变量存储地址,因此String[] a
已准备好从words[2]
中存储的地址中获取地址(引用)。以这种方式,它们指向内存中的相同空间,即一维数组[g, h, i]
当你去改变words[2]
并在a
中看到相同的变化时,这是因为对数组的写入仅改变了指向的内存空间,而不是指针。 a
和words[2]
将始终具有相同的值。