1

我正在从 java 认证书中做一些练习。在关于垃圾收集的问题中,他们提供了以下代码:

class Test {
   private Demo d;
   void start() {
      d = new Demo();
      this.takeDemo(d);
   }
   void takeDemo(Demo demo) {
      demo = null;
      demo = new Demo();
   }
}

问题是

在第 4 行创建的 Demo 对象何时有资格进行垃圾回收?

我会说它可以在指令 demo=null; 之后收集。因为不再引用它,但他们给出的答案是:

当运行此代码的实例符合垃圾回收条件时

我错过了什么?

4

6 回答 6

5

Java 是“按值传递”,因此该语句仅影响indemo = null;的本地副本。它不设置为,因此只要封闭实例可访问,就可以访问。demotakeDemodnull

于 2013-02-08T12:26:31.847 回答
1

您正确地注意到demo设置为null. 但d不是。它仍然持有对同一个对象的引用。因此得到了答案。

于 2013-02-08T12:27:09.877 回答
1

因为demo = null只是改变方法参数的值demo,它是方法本地的,不影响字段的值d。请记住,在 Java 中,所有方法参数都是按值传递的。

于 2013-02-08T12:27:25.237 回答
0

在方法完成之前,对局部变量的引用d是“活动的” 。start()在此之前,垃圾收集不应该释放它。

于 2013-02-08T12:26:37.890 回答
0

第 4 行的 Demo 只能与 Test 实例一起收集。或者如果你再次调用 start 方法(旧的 Demo 将被收集并创建新的)

takeDemo 方法对第一个 Demo 没有影响。但它创建了第二个演示。在 takeDemo 方法完成后可以立即收集第二个 Demo。

于 2013-02-08T12:28:43.670 回答
0

当你调用 this.takeDemo(d); 引用 d 的值被复制到参数 demo 所以 d 和 demo 都引用在第 4 行中创建的对象。现在在方法内部,当您将变量 demo 设置为指向 null d 时仍然持有一个引用,因此该对象将是一旦 Test 类的实例被垃圾收集,就有资格进行垃圾收集。

于 2013-02-08T12:56:27.303 回答