我一直在阅读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]
这会使过时的对象引用为空,而不必为数组创建新的对象。
答案 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] = null
在size
字段的预先递减之前没有意义,并且会导致访问超出范围。
答案 2 :(得分:0)
在您建议的实现中,您已切换顺序,因此设置为null时的大小与上面的索引不同。如果你先做elements[--size] = null;
,你就会失去你想要归还的参考。因此,您需要另一个句柄(在清除该引用的内部记录之前引用数据。您想要删除内部引用,以便在不再需要时可以对对象进行垃圾回收。保持它超过大小虽然不可访问,但会导致GC无法释放该对象。