1 package com.twoslow.cha2;
2
3 import java.util.Arrays;
4 import java.util.EmptyStackException;
5
6 public class Stack {
7
8 private Object[] elements ;
9
10 private int size = 0;
11
12 private static final int DEFAULT_INITIAL_CAPACITY = 16 ;
13
14 public Stack() {
15 elements = new Object[DEFAULT_INITIAL_CAPACITY] ;
16 }
17
18 public void push(Object e) {
19 ensureCapacity() ;
20 elements[size++] = e ;
21 }
22
23 public Object pop() {
24 if(size == 0)
25 throw new EmptyStackException() ;
26 Object result = elements[--size] ;
27 /*
28 *下列3种情形需要考虑手动处理资源:
29 *1) 类是自己管理内存,如例子中的 Stack 类。
30 *2) 使用对象缓存机制时,需要考虑被从缓存中换出的对象,或是长期不会被访问到的对象。
31 *3) 事件监听器和相关回调。用户经常会在需要时显示的注册,然而却经常会忘记在不用的时候注销这些回调接口实现类。
32 *
33 *
34 *当我们调用 pop 方法是,该方法将返回当前栈顶的 elements,
35 *同时将该栈的活动区间(size)减一,
36 *然而此时被弹出的 Object 仍然保持至少两处引用,
37 *一个是返回的对象,另一个则是该返回对象在 elements 数组中原有栈顶位置的引用。
38 *这样即便外部对象在使用之后不再引用该 Object,那么它仍然不会被垃圾收集器释放,久而久之导致了更多类似对象的内存泄露
39 */
40 elements[size] = null ;
41 return result;
42 }
43
44 private void ensureCapacity() {
45 if(elements.length == size)
46 elements = Arrays.copyOf(elements, 2 * size + 1) ;
47 }
48
49 }