import java.util.EmptyStackException;
public class Stack {
//有了記憶體回收功能,我們就不需要考慮記憶體管理了嗎?? NO!!
/**
*何時需要手工清Null 參考??
*1.一旦一個類自己管理它的記憶體,我們就應該警惕記憶體泄露的問題了。
* 一旦一個元素被釋放掉,該元素中包含的所有對象引用都要被清除
*2.緩衝,因為放在緩衝中的對象引用很容易被遺忘,以至於它不再被用之後的很長一段時間內仍然留在緩衝中。
* 一個方法是用WeakHashMap代替緩衝,另外一個方法需要java.util.TimerAPI來完成
*/
private Object[] elements;
privateintsize=0;
public Stack(int initialCapacity){
this.elements = new Object[initialCapacity];
}
publicvoid push(Object obj){
ensureCapacity();
elements[size++] = obj;
}
public Object pop(){
if (size== 0)
thrownew EmptyStackException();
/**
*注意:不嚴格的講,下面這條語句可能會導致"記憶體泄露"
*因為如果一個棧先是增長,然後再收縮,那麼棧中彈出來的對象將不會被當作記憶體回收(即使使用
*棧的客戶程式不再引用這些對象),因為棧內部維護著這些對象的到期引用(obsoletereference
*,是指永遠也不會被解除的引用),本例而言,elements數組的“即時區域(activeportion,
*指下標小於size的那部分)之外的引用都是到期的”
*/
//return elements[--size];
/**
*修改如下
*清空到期引用的另一個好處是,如果它們以後又被錯誤地解除引用,程式就會馬上拋出
*NullPointerException異常,而不是悄悄地錯誤運行
*/
Object result = elements[--size];
elements[size]=null;
return result;
}
//ensure space for at least one more element,roughly doubling the
//capacity each time the array needs to grow
privatevoid ensureCapacity(){
if(elements.length == size){
Object[] oldElements = elements;
elements = new Object[2* elements.length+1];
System.arraycopy(oldElements, 0, elements, 0, size);
}
}
publicstaticvoid main(String[] args) {
Stack s = new Stack(0);
for (int i=0; i<100; i++)
s.push(i);
for (int i=0; i<100; i++)
System.out.println(s.pop());
}
}