3
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();
     }
}

There is two objectcs eligible for garbage collection but one is difficult to understand.

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

1) This line I thing that it would make this

A d = new A().aob = new A();
          ^             ^
          O1            O2

      O1 --> O2 --> null
      ^
      |
d ----| 

2) But what really is doing is this (so one eligible object) WHY IS LIKE THIS?

A d = new A().aob = new A();
          ^             ^
          O1            O2

      O1 --> O2 --> null
             ^
             |
d -----------| 

because the assignements are associative right to left.

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

Could anyone explain it otherwise? Thanks

Joe
  • 7,749
  • 19
  • 60
  • 110
  • Two points: First, your second diagram should have `O2 --> O1 --> null`. Second, the other object eligible for gc is the original instance of `A` assigned to `c` in `A c = new A();`. Presumably you knew this one, but it wasn't mentioned so I thought I'd mention it. :) – Ted Hopp Mar 07 '12 at 20:53

3 Answers3

6

It starts from right to left. First new A() is executed and a new object is created. Then it is assigned to the field aob of another new object A. Finally d is referencing the property aob. This means the second object A is eligible for garbage collection.

It is like:

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

But the secondA object is created inline so there are no references to it and it is eligible for garbage collection.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • A d = new A().aob = new A(); ---- will be the same as --- A d = new A(); new A().aob = d; – Joe Mar 07 '12 at 22:09
0

In this example what would you expect?

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

would d be the instance a or the instance b?

Would you expect it to be different just because you are creating the objects inline?

in this example surely d must be object b, and so object a is not referenced and can be garbage collected.

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
0
A d = new A().aob = new A();

In Java, the assignment operator is right-associative, i.e. they are evaluated from right-to-left. But also, they are in the least precedence operators group.

So the second new operator (right of the second equality) is evaluated first and we get a new A object; let's say 'a'. Now we have:

new A().aob = a;

The trick here is to recognize the operator precedence. Take a look at here: http://pages.cs.wisc.edu/~willb/cs302/spring-07/java-operator-precedence.pdf

The 'new' operator and the '.' method call operator have the same precedence but their associative quality are reversed: 'new' is right-associative and '.' is left-associative.

So the compiler first applies the new operator on the 'right operand' which is here 'A()' (before the next operand comes into place). Let's call the new object b; and we have:

A d = b.aob = a;

The compiler now needs to apply the '.' operator first (as '.' has higher precedence than '=' operator). Let's call the object referred by 'b.aob' as c:

A d = c = a;

Finally all that is left are the assignment operators and they are right-associative (evaluated from right-to-left). So, a is assigned to c (b.aob) first, and then c is assigned to d.

Cagil Seker
  • 333
  • 2
  • 9