0

我一直在阅读 Effective Java,我发现过时的对象引用项给我的一件事是他的实现pop()

public Object pop(){
  if (size == 0)
    throw new EmptyStackException();

  Object result = elements[--size];
  elements[size] = null;
  return result;
}

为什么有必要创建一个新的引用elements?为什么不做

elements[size] = null;
return elements[--size]

这将清除过时的对象引用,而不必为数组创建新的引用。

4

3 回答 3

3

请注意,您的更改会反转行为,假设size = 5,让我们看看会发生什么:

原文(--先到):

Object result = elements[4];
elements[4] = null;
return result;

现在你的改变(--排在第二位):

elements[5] = null;
return elements[4]

所以你的实现将返回一个不正确的值。实现需要拉出头部,然后将其设置为null作为单独的步骤,否则被移除的值会丢失。查看此实现,理论上您可以不将值设置为 null,这将节省几行代码,但可能会引入相当严重的内存泄漏风险(在其他任何地方都已 de -引用它们)。此外,单独的行使这种行为更加明确,这对于以后重新访问代码的人很有价值。冗长有时是你的朋友。

于 2013-11-22T15:36:50.047 回答
1

这是因为elements[size] = null在预先减少字段之前没有意义,size并且会导致访问超出范围。

于 2013-11-22T15:36:13.797 回答
0

在您建议的实现中,您已经切换了顺序,因此设置为 null 时的大小与上面的索引不同。如果你先做elements[--size] = null;,你会失去你打算返回的参考。出于这个原因,您需要另一个句柄(在清除该引用的内部记录之前引用数据。您希望删除内部引用,以便在不再需要时可以对对象进行垃圾回收。保持它超过大小,虽然不可访问,但会导致 GC 无法释放对象。

于 2013-11-22T15:38:04.100 回答