我认为关键的误解体现在:
我认为我声明了x,然后y 指的是x。
Java 中的变量持有 references 到 objects(和原语,但这在这里并不重要)。唯一可以被变量引用的是对象。变量不是对象,因此没有任何东西可以引用它们。让我们更仔细地考虑这两个代码示例。
第一种情况,有两个变量和一个数组:
public static void main(String[] args) {
String[] x = {"A"};
String[] y = x;
x[0] = "B";
System.out.print(x[0] + " " + y[0]);
}
考虑哪些事物是实际值,哪些事物只是引用实际值的引用、指针或句柄(各种)名称,这可能会有所帮助。 x 和 y 都是变量,这些变量的 值 是对对象的引用(在这种情况下,是字符串数组)。在这种情况下,x 的特定值与y 的值相同,它是对具有一个元素的数组的引用,即字符串"A"。表达式x[0] 是通过检索变量x 具有引用的数组并获取其第一个元素来计算的。表达式y[0] 是通过检索变量y 具有引用的数组并获取其第一个元素来计算的。因为x 和y 持有对same 数组的引用,所以数组的第一个元素与其自身相同。打印输出为B B。
第二种情况,有两个变量,没有数组。
public static void main(String[] args) {
String x = "A";
String y = x;
x = "B";
System.out.print(x + " " + y);
}
变量x 持有对字符串"A" 的引用。第一个赋值 String y = x; 使 y 持有对同一字符串 "A" 的引用。此时,如果您可以修改有关字符串的任何内容(但您不能在 Java 中,因为字符串是不可变的),您可以使用 x 或 y 进行修改,您会看到结果,因为 both 变量都引用了一个 single 对象。然而,第二个赋值x = "B"; 使x 的值 成为对不同字符串"B" 的引用。它不会改变y 的值,它仍然是对字符串"A" 的引用。因此,表达式x 被求值,因为x 持有对字符串"B" 的引用,所以结果是"B"。表达式y 被求值,因为y 持有对字符串"A" 的引用,所以结果是"A"。打印输出为B A。
也许关键点是变量和对象是完全不同的。对象存在,期间。变量保存对对象的引用。当你做类似的事情时
x.doSomething();
您正在检索x 的值,它是一个对象,然后调用该对象的doSomething() 方法。您可以检索变量引用的对象,并且可以使变量引用不同的对象(通过赋值)。这些是唯一你可以对变量做的事情。你能做的任何其他事情,都是在对一个对象做。这在以下情况下尤其重要:
String[] x = {"A"}; ; there's an array {"Α"} and the variable `x` _refers_ to it
String[] y = x; ; retrieve the array to which `x` refers, and make `y` refer to it, too
x[0] = "B"; ; retrieve the array to which `x` refers (and to which `y` also refers)
; and make "B" its first element.
String x = "A"; ; there's a string "A", and the variable `x` _refers to it
String y = x; ; retrieve the string to which `x` refers, and may `y` refer to it, too
x = "B"; ; make `x` refer to the string "Β" (has no effect on what `y` refers to)