Сколько объектов подходит для сборщика мусора - PullRequest
3 голосов
/ 08 марта 2012
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 ]

6 голосов
/ 08 марта 2012

Начинается справа налево.Сначала выполняется new A() и создается новый объект.Затем ему присваивается поле aob другого нового объекта A.Наконец, d ссылается на свойство aob.Это означает, что второй объект A подходит для сборки мусора.

Это похоже на:

A firstA = new A();
A secondA = new A();
secondA.aob = firstA;
A d = secondA.aob;

Но объект secondA создается встроенным, поэтому на него нет ссылокон имеет право на сборку мусора.

0 голосов
/ 08 марта 2012
A d = new A().aob = new A();

В Java оператор присваивания является ассоциативным справа, т. Е. Он оценивается справа налево. Но они также входят в группу операторов с наименьшим приоритетом.

Итак, второй новый оператор (справа от второго равенства) вычисляется первым, и мы получаем новый объект A; скажем, ' a '. Теперь у нас есть:

new A().aob = a;

Хитрость в том, чтобы распознать приоритет оператора. Посмотрите здесь: http://pages.cs.wisc.edu/~willb/cs302/spring-07/java-operator-precedence.pdf

Оператор 'new' и символ '.' Операторы вызова метода имеют тот же приоритет, но их ассоциативное качество меняется на обратное: «новый» является правоассоциативным, а «.» является левоассоциативным.

Таким образом, компилятор сначала применяет новый оператор к «правому операнду», который здесь «A ()» (до того, как следующий операнд вступит в действие). Давайте назовем новый объект b ; и имеем:

A d = b.aob = a;

Теперь компилятору нужно применить '.' оператор первый (так как «.» имеет более высокий приоритет, чем оператор «=»). Давайте назовем объект, на который ссылается b.aob, c :

A d = c = a;

Наконец, все, что осталось, это операторы присваивания, и они ассоциативны справа (оцениваются справа налево). Итак, a назначается сначала c (b.aob), а затем c назначается d .

0 голосов
/ 08 марта 2012

В этом примере, что вы ожидаете?

A a = new A();
A b = new A();
a.aob = b;
A d = a.aob;

будет d экземпляром a или экземпляром b?

Вы ожидаете, что он будет другимтолько потому, что вы создаете объекты inline?

в этом примере, безусловно, d должен быть объектом b, и поэтому на объект a нет ссылки, и его можно собирать мусором.

...