Объект a = объект b; что происходит с объектом?
Один из моих преподавателей дал нам несколько практических вопросов для экзамена, и один из вопросов - это что-то вроде ниже (psuedocode):
a.setColor(blue);
b.setColor(red);
a = b;
b.setColor(purple);
b = a;
//what color is a, and what color is b?
Мне кажется чрезвычайно рудиментарным, поэтому я предложил ответ, что "красный", а "красный", но мне сказали, что это неверно. Я сломал свой ответ, как бы математическую задачу:
a = 15;
b = 12;
a = b; //a becomes 12
b = 13;
b = a; //b becomes 12
Но мой мыслительный процесс происходит через ум C, а не Java. Я подумал, что есть какой-то универсальный метод для обоих, но, возможно, я ошибаюсь? Является ли мой ответ неправильным или мой профессор ошибается? Я очень новичок в Java, хотя у меня есть команда C, Python и веб-логики (PHP, Ruby), поэтому я извиняюсь, если это что-то тривиальное (что есть).
Ответы
Ответ 1
Предполагая, что вы уже создали два объекта, а переменные 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
.
Ответ 2
Это потому, что в первом примере a
и b
есть объекты, поэтому это происходит на каждом из шагов:
a < - - объект
b < - - объект
a.setColor(синий); < - a
становится синим.
b.setColor(красный); < - b
становится красным
a = b; < - ВАЖНО:: оригинальный a
объект выпущен и доступен для коллекции мусора, а теперь a
содержит ссылку b
object, которые означают a
и b
, относятся к одному и тому же объекту, который равен b
.
b.setColor(фиолетовый); < - b теперь является фиолетовым. Так как a только точки b, a также фиолетовый
Ответ: оба a
и b
фиолетовые в этой точке.
Ответ 3
Важно, что после строки a = b
у вас больше нет двух объектов. У вас есть две переменные, относящиеся к одному и тому же объекту. Поэтому, когда вы меняете цвет этого объекта, обе переменные отражают его. строка b = a
фактически ничего не делает.
Ответ 4
В Java обычно правильнее думать о любой переменной, которая является объектом как указатель на значение этого типа объекта. Поэтому в Java:
Color a = new Color(), b = new Color();
a.setColor(blue);
b.setColor(red);
a = b;
b.setColor(purple);
b = a;
В С++ должно быть более или менее то же, что и в С++:
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
(Обратите внимание, что это НЕ то же самое, что и ссылки - по в этой статье).
Также обратите внимание, что для примитивов переменные Java - это просто значения - НЕ указатели. Таким образом, в случае примитивных целых чисел он должен вести себя более или менее, как вы ожидаете в своем вопросе, поскольку a = b
устанавливает значение a
равным значению b
.
Ответ 5
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.
Ответ 6
Поскольку все остальные объяснили разницу между ссылками и примитивами, я объясню, как это работает под поверхностью.
Таким образом, ссылка на объект по существу является числом. В зависимости от ВМ это будет либо 32 бита, либо 64 бита, но это еще число. Это число говорит, что вы были в памяти объекта. Эти числа называются адресами и обычно записываются в шестнадцатеричной базе, например, 0xYYYYYYYY
(это пример 32-разрядного адреса, 64-разрядный адрес будет в два раза больше).
Используйте приведенный выше пример с помощью 32-разрядной виртуальной машины
a.setColor(blue); // Let assume the object pointed to by a is at 0x00000001
b.setColor(red); // Let 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 и С++, которые обеспечивают доступ к более низкому уровню, это становится более очевидным и важным.
Арифметика?. Можете ли вы сделать арифметику и другие вещи, которые вы можете делать с цифрами? Более короткий ответ - нет, не в java, по крайней мере.
В C и С++ добавочные и декрементирующие указатели на объекты, однако, совершенно допустимы и используются много, например, для перемещения массивов.
Не стесняйтесь задавать вопросы, если это недостаточно ясно.