有多少个符合垃圾收集器的对象

时间:2012-03-07 20:37:54

标签: java garbage-collection scjp ocpjp

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 个答案:

答案 0 :(得分:6)

从右到左开始。执行第一个new A()并创建一个新对象。然后将其分配给另一个新对象aob的字段A。最后d引用了属性aob。这意味着第二个对象A符合垃圾回收的条件。

就像:

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

secondA对象是内联创建的,所以没有对它的引用,它有资格进行垃圾回收。

答案 1 :(得分:0)

在这个例子中你会期待什么?

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

d是实例a还是实例b

您是否期望它因为您在线创建对象而有所不同?

在此示例中,d必须是对象b,因此对象a未被引用,可以进行垃圾回收。

答案 2 :(得分:0)

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'运算符和'。'方法调用操作符具有相同的优先级,但它们的关联质量是相反的:'new'是右关联的和'。'是左联想的。

因此编译器首先在'右操作数'上应用new运算符,这是'A()'(在下一个操作数到位之前)。我们称之为新对象 b ;我们有:

A d = b.aob = a;

编译器现在需要应用'。' operator first(因为'。'的优先级高于'='运算符)。我们将'b.aob'引用的对象称为 c

A d = c = a;

最后剩下的就是赋值运算符,它们是右关联的(从右到左计算)。因此,首先将 a 分配给 c (b.aob),然后将 c 分配给 d