垃圾收集器有多少个对象符合资格?

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

有两个对象可以进行垃圾回收,但其中一个很难理解。

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

有没有其他方式可以解释一下?谢谢。

两点:首先,你的第二个图应该是 O2 --> O1 --> null。其次,另一个可以进行垃圾回收的对象是在 A c = new A(); 中分配给 cA 类型的原始实例。也许你已经知道了这一点,但它没有被提到,所以我想提一下。 :) - Ted Hopp
3个回答

6

这段代码从右到左执行。首先执行new A(),创建一个新对象。然后将其分配给另一个新对象A的字段aob。最后,d引用属性aob。这意味着第二个对象A可以进行垃圾回收。

就像这样:

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

但是secondA对象是内联创建的,因此没有引用它,它可以被垃圾回收。


一个d = new A().aob = new A(); ---- 等同于 --- A d = new A(); new A().aob = d; - Joe

0
在这个例子中,你会期望什么?
A a = new A();
A b = new A();
a.aob = b;
A d = a.aob;

在这个例子中,d 应该是对象 b 的实例还是对象 a 的实例?

你认为仅仅因为你在内联创建对象,它们就会有所不同吗?

在这个例子中,d 显然应该是对象 b,因此对象 a 没有被引用,可以被垃圾回收。


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

在Java中,赋值运算符是右结合的,即它们从右到左进行评估。但同时,它们也属于最低优先级运算符组。
因此,第二个new运算符(在第二个等号的右侧)首先被评估,我们得到一个新的A对象;假设为“a”。现在我们有:
new A().aob = a;

这里的诀窍是要认识到运算符优先级。看一下这里:http://pages.cs.wisc.edu/~willb/cs302/spring-07/java-operator-precedence.pdf

'new' 运算符和 '.' 方法调用运算符具有相同的优先级,但它们的结合性是相反的:'new' 是右结合的,而 '.' 是左结合的。

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

A d = b.aob = a;

编译器现在需要首先应用'.'运算符(因为'.'比'='运算符的优先级更高)。让我们把'b.aob'所引用的对象称为c
A d = c = a;

最后剩下的就是赋值操作符,它们是从右到左结合的。因此,首先将 a 分配给 c (b.aob),然后再将 c 分配给 d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接