Сколько объектов подходит для сборщика мусора

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.

Другие вопросы по тегам