Сколько объектов подходит для сборщика мусора
class A{
A aob;
public static void main(String args[]){
A a=new A();
A b=new A();
A c=new A();
a.aob=b;
b.aob=a;
c.aob=a.aob;
A d=new A().aob=new A(); //tricky assignement
c=b; //one object eligible GC
c.aob=null;
System.gc();
}
}
Существует два объекта, подходящих для сбора мусора, но один трудно понять.
A d=new A().aob=new A();
1) В этой строке я думаю, что это сделает
A d = new A().aob = new A();
^ ^
O1 O2
O1 --> O2 --> null
^
|
d ----|
2) Но что на самом деле делает этот (так один подходящий объект) ПОЧЕМУ ЭТО ТАК?
A d = new A().aob = new A();
^ ^
O1 O2
O1 --> O2 --> null
^
|
d -----------|
потому что назначения являются ассоциативными справа налево.
A d = ( new A().aob = new A() );
Может ли кто-нибудь объяснить это иначе? Спасибо
3 ответа
Это начинается справа налево. Первый new A()
выполняется и создается новый объект. Затем он назначается на поле aob
другого нового объекта A
, в заключение d
ссылается на собственность aob
, Это означает, что второй объект A
имеет право на сборку мусора.
Это как:
A firstA = new A();
A secondA = new A();
secondA.aob = firstA;
A d = secondA.aob;
Но secondA
Объект создается встроенным, поэтому на него нет ссылок, и он пригоден для сборки мусора.
В этом примере, что вы ожидаете?
A a = new A();
A b = new A();
a.aob = b;
A d = a.aob;
было бы d
быть примером a
или экземпляр b
?
Вы ожидаете, что это будет отличаться только потому, что вы создаете объекты встроенными?
в этом примере наверняка d
должен быть объектом b
и так возражают a
не ссылается и может быть сборщиком мусора.
A d = new A().aob = new A();
В Java оператор присваивания является ассоциативным справа, т. Е. Они оцениваются справа налево. Но они также входят в группу операторов с наименьшим приоритетом.
Таким образом, второй новый оператор (справа от второго равенства) вычисляется первым, и мы получаем новый объект A; скажем "а". Теперь у нас есть:
new A().aob = a;
Хитрость в том, чтобы распознать приоритет оператора. Посмотрите здесь: http://pages.cs.wisc.edu/~willb/cs302/spring-07/java-operator-precedence.pdf
"Новый" оператор и "." Операторы вызова метода имеют тот же приоритет, но их ассоциативное качество меняется на обратное: "новый" является правоассоциативным, а "." левоассоциативен.
Таким образом, компилятор сначала применяет новый оператор к "правому операнду", который здесь "A()" (до того, как следующий операнд вступит в действие). Давайте назовем новый объект b; и у нас есть:
A d = b.aob = a;
Компилятор теперь должен применить '.' оператор первый (так как "." имеет более высокий приоритет, чем оператор "="). Давайте назовем объект, называемый 'b.aob', как c:
A d = c = a;
Наконец, все, что осталось, это операторы присваивания, и они ассоциативны справа (оцениваются справа налево). Итак, a назначается сначала c (b.aob), а затем c назначается d.