Generic stack implementation

The underlying issue is type erasure. The relevant implications of this means that an instance of the Stack class doesn’t know it’s type arguments at run-time. This is the reason why you can’t just use the most natural solution here, array = new T[maxSize].

You’ve tried to work around this by creating an array using Array.newInstance(...), but unfortunately this array does not have elements of type T either. In the code shown the elements are of type StackArray, which is probably not what you intended.

One common way of dealing with this is to use an array of Object internally to Stack, and cast any return values to type T in accessor methods.

class StackArray<T> implements Stack<T> {
    private int maxSize;
    private Object[] array;
    private int top;

    public StackArray(int maxSize) {
        this.maxSize = maxSize;
        this.array = new Object[maxSize];
        this.top = -1;
    }

    // ... lines removed ...

    public T pop() {
        if(this.isEmpty())
            throw new EmptyStackException();
        return element(top--);
    }

    public T peek() {
        if(this.isEmpty())
            throw new EmptyStackException();
        return element(top);
    }

    // Safe because push(T) is type checked.
    @SuppressWarnings("unchecked")
    private T element(int index) {
        return (T)array[index];
    }
}

Note also you have a bug in the resizeArray() method where maxSize is never assigned a new value. You don’t really need to keep track of maxSize, as you could just use array.length.

I think there is also an issue with peek() when the stack is empty in the original code.

Leave a Comment