public class DemoCheckedStack {
    static final class FullStackException extends Exception {
        private static final long serialVersionUID = 1L;
        private final int capacity;
        private final int rejectedValue;

        FullStackException(int capacity, int rejectedValue) {
            super("full stack");
            this.capacity = capacity;
            this.rejectedValue = rejectedValue;
        }

        int capacity() {
            return capacity;
        }

        int rejectedValue() {
            return rejectedValue;
        }
    }

    static final class CheckedStack {
        private final int[] elements;
        private int size;

        CheckedStack(int capacity) {
            if (capacity <= 0) {
                throw new IllegalArgumentException("nonpositive capacity");
            }
            elements = new int[capacity];
        }

        void push(int value) throws FullStackException {
            if (size == elements.length) {
                throw new FullStackException(elements.length, value);
            }
            elements[size++] = value;
        }

        int size() {
            return size;
        }
    }

    public static void main(String[] args) {
        CheckedStack stack = new CheckedStack(2);
        try {
            stack.push(7);
            stack.push(12);
            stack.push(99);
        } catch (FullStackException error) {
            System.out.println(error.getMessage() + ": " + error.capacity());
            System.out.println("rejected: " + error.rejectedValue());
        }
        System.out.println("size: " + stack.size());
    }
}
