我的一位教授为考试提供了一些练习题,其中一个问题如下(伪代码):
a.setColor(blue);
b.setColor(red);
a = b;
b.setColor(purple);
b = a;
//what color is a, and what color is b?
这对我来说似乎非常简陋,所以我提出的答案是a'是'红色',b是'红色',但我被告知这是不正确的。我打破了答案,因为我会解决数学问题:
a = 15;
b = 12;
a = b; //a becomes 12
b = 13;
b = a; //b becomes 12
但我的思维过程是通过C的思想,而不是Java。我认为两者都有一些通用的方法,但也许我错了?我的回答是错的还是我的教授错了?我对Java很新,虽然我有一些C,Python和Web逻辑(PHP,Ruby)的命令,所以如果这是一件微不足道的事情我会道歉(就是这样)。
答案 0 :(得分:15)
假设您已经创建了两个对象,并且变量a
和b
引用了它们,那么您最初会得到类似的东西。
a --> [ white ] b --> [ white ]
你的前两行改变了对象的颜色,给你
a --> [ blue ] b --> [ red ]
然后,将变量a
指向b
引用的对象,以便它们都引用同一个对象。你现在有了
[ blue ] b --> [ red ] <-- a
然后更改b
引用的对象的颜色。
[ blue ] b --> [ purple ] <-- a
最后,第b=a;
行不执行任何操作,因为b
已经引用与a
相同的对象。
答案 1 :(得分:6)
这是因为在第一个例子中,a
和b
是对象,所以这就是每个步骤中发生的事情:
a&lt; - 是一个对象
b&lt; - 是一个对象
a.setColor(蓝色); &lt; -
a
变为蓝色b.setColor(红色); &lt; -
b
变为红色a = b; &lt; - 重要 :: 原始
a
对象已发布并可用于垃圾回收,现在a
保留b
的引用{1}}对象,表示a
和b
现在指的是同一个对象,即b
。b.setColor(紫色); &lt; - b现在是紫色的。由于只有b点,a也是紫色
回答:此时a
和b
都是紫色。
答案 2 :(得分:3)
要实现的重要一点是,在行a = b
之后,您不再有两个对象。你有两个变量,都指向同一个对象。因此,当您更改该对象的颜色时,两个变量都会反映它。 b = a
行实际上没有做任何事情。
答案 3 :(得分:3)
在Java中,将任何作为Object的变量视为指向该Object类型值的指针通常是正确的。因此,Java中的以下内容:
Color a = new Color(), b = new Color();
a.setColor(blue);
b.setColor(red);
a = b;
b.setColor(purple);
b = a;
在C ++中应该与以下内容大致相同:
Color *a = new Color();
Color *b = new Color();
a->setColor(blue); // the value a points to is now blue
b->setColor(red); // the value b points to is now red
a = b; // a now points to the same value as b.
b->setColor(purple); // the value BOTH a and b point to is now purple
b = a; // this does nothing since a == b is already true
(请注意, NOT 与引用相同 - 根据this article)。
另请注意,对于原语,Java变量只是值 - 而不是指针。因此,在原始整数的情况下,它应该在您的问题中表现得或多或少,因为a = b
将a
的值设置为等于b
的值。 / p>
答案 4 :(得分:2)
a
和b
是对象的引用。当您编写a=b
时,会将a分配给先前分配给b
的引用,因此它们现在都引用相同的对象。
所以,假设您有两个对象,O1和O2,它们在开头分别分配给a
和b
。
a.setColor(blue); // the object O1 is set the color blue
b.setColor(red); // the object O2 is set the color red
a = b; // a now references O2, and b still references O2.
b.setColor(purple); // the object O2 is set the color purple.
b = a; // b is told to reference O2, which it already is.
如果你想通过C的思想,你可以看到a
和b
作为指针,可以在变量之间交换,并且可以修改其数据。
原始值的处理方式与C中的处理方式不同。
答案 5 :(得分:2)
由于其他人已经解释了引用和原语之间的区别,我将解释它在表面下是如何工作的。
因此对对象的引用本质上是一个数字。取决于VM,它将是32位或64位,但它仍然是一个数字。这个数字告诉你对象是在内存中。这些数字称为地址,通常用十六进制编写,如0xYYYYYYYY
(这是一个32位地址的例子,64位地址的两倍大)。
让我们使用上面的例子,使用32位VM
a.setColor(blue); // Let's assume the object pointed to by a is at 0x00000001
b.setColor(red); // Let's assume the object pointed to by b is at 0x00000010
/* Now the following makes sense, what happens is the value of
a (0x00000001) is overwritten with 0x00000010.
This is just like you would expect if a and b were ints.
*/
a = b; // Both a and b have the value 0x00000010. They point to the same object
b.setColor(purple); // This changed the object stored at 0x00000010
b = a; // This says nothing because both a and b already contain the value 0x00000010
这应该说明引用确实像您在第二个示例中所示的那样工作。然而,只有表面上,就程序员而言,引用的赋值不像赋值原语一样。
在Java中,您永远不必担心对象等的地址。在C和C ++这样的语言中,它们可以实现更低级别的访问,这一点变得更加明显和重要
Arithmetics?那么你可以做算术和其他你可以用数字做的东西吗?较短的答案是否定的,至少在java中不是。
在C和C ++中,递增和递减指向对象的指针是完全有效的,并且使用了很多,例如遍历数组。
如果不够清楚,请随时提问。