import java.util.EmptyStackException;
public class Stack {
//有了垃圾回收功能,我们就不需要考虑内存管理了吗?? NO!!
/**
*何时需要手工清空引用??
*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());
}
}