有效的Java Item 6 - Stack pop实现

时间:2013-11-22 15:33:05

标签: java effective-java

我一直在阅读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]

这会使过时的对象引用为空,而不必为数组创建新的对象。

3 个答案:

答案 0 :(得分:3)

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

原创(--优先):

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

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

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

因此,您的实现将返回不正确的值。实现需要拉出头部,然后将其设置为null作为单独的步骤,否则删除的值将丢失。看看这个实现,你理论上可以不将值设置为null,这样可以节省几行代码,但可能会引入相当严重的内存泄漏风险(在其他地方出现之后保持堆栈顶部上方的大对象) - 引用他们)。此外,单独的行使这种行为更加明确,这对于以后重新访问代码的人来说很有价值。详细程度有时是你的朋友。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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