9

我有这段代码用于 Stack 的 pop 方法,我试图弄清楚它如何避免徘徊,同时仍然返回我们的索引当前指向的元素:

public String pop()
{ // Remove item from top of stack.
String item = a[--N];
a[N] = null; // Avoid loitering (see text).
if (N > 0 && N == a.length/4) resize(a.length/2);
return item;
}

据我所知,我们将 String 对象的引用项指向数组 a 的索引元素(我们从最后一个元素开始,使用它的当前大小 N-1 因此递减)。那么,如果我们要返回引用,为什么要在这样做之前将引用指向的索引元素设置为 null 呢?这不会使项目指向任何东西并且什么都不返回吗?

4

2 回答 2

19

只要对象是可访问的,它就不能被垃圾收集。如果您只是使用更改索引--N但不使用 nullify a[N],您将保留对该对象的引用,即使客户端代码不再引用该对象,也会阻止其垃圾收集。

这是您需要在 Java 中使变量无效的唯一情况之一。

您似乎也误解了引用是什么。a[N]包含一个指向内存中对象的值。当您写入时String item = a[N],您将该值复制到变量item中。两个变量 (itema[N]) 现在都指向同一个对象。然后,当您 writea[N] = null时,您从数组中删除了该引用,但item仍包含一个指向原始对象的值。

于 2013-08-07T17:33:05.787 回答
3

这将复制数组中的引用。它不引用数组成员。

 String item = a[--N];

现在你有两个对同一个对象的引用,一个在局部变量中,一个在数组中。这将删除数组中的副本:

 a[N] = null; // Avoid loitering (see text).

如果它没有从数组中删除,那么不必要的引用将继续存在,从而阻止垃圾收集。

于 2013-08-07T17:34:10.487 回答