简体   繁体   中英

Throwing exceptions for a pop() method in Java

For one of my classes, I've been assigned to create my own Stack class, alongside the methods push(), pop(), and size(). The full code is here:

    public class Stack {

    private int maxStackSize, topOfStack;
    private int[] stack;

    public Stack(int maxStackSize) {
        if (maxStackSize <= 0)
            System.out.println("Stack size should be a positive integer.");
        else {
            this.maxStackSize = maxStackSize;
            topOfStack = -1;
            stack = new int[maxStackSize];
        }
    }

    public void push(int val) { 
        if(topOfStack == maxStackSize - 1)
            System.out.println("Cannot push! Stack is full.");
        else
            stack[++topOfStack] = val;
    }

    public int pop() { 
        if (topOfStack == -1)
            throw new ArrayIndexOutOfBoundsException("Cannot pop! Stack is empty.");
        else
        return stack[topOfStack--];
    }

    public int size() { 
        return (topOfStack+1);
    }
}

The methods are working correctly aside from an issue with pop(). I need to check if the stack is empty, which is the "if" statement, and display the error message "Cannot pop. Stack is empty" if there is nothing in the stack, However, I don't have an integer to return for the "if" part of the if-else, so I've been trying to throw the exception instead. as you can see with what I've attempted.

public int pop() { 
    if (topOfStack == -1)
        throw new ArrayIndexOutOfBoundsException("Cannot pop! Stack is empty.");
    else
    return stack[topOfStack--];
}

However, I am still getting the exception message, but now it's just accompanied by my own message, "Cannot pop. Stack is empty:" The full exception I am getting is this:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Cannot pop! Stack is empty.
    at Stack.pop(Stack.java:25)
    at Main.main(Main.java:6)

If possible, I'd like to not display the exception, and only display the message, "Cannot pop. Stack is empty" when encountering an empty stack? Is there a way to do this? Am I just throwing the exception incorrectly. Any help is appreciated.

It's displaying the error message because you are throwing the error with throw new ArrayIndexOutOfBoundsException("Cannot pop. Stack is empty;");

If you don't want the error then just print the message to the console without it.

Good news: you're not throwing the exception "wrong". The issue is with how the code that's calling your pop() method handles (or doesn't handle) the exception. That code is responsible for deciding what to do if pop() throws an exception, and depending on what that code is, you may or may not have any say in the matter.

For instance, if pop() is being called by some automated test or evaluation framework provided by your instructor to which you don't have access, you're stuck with whatever exception-handling behavior the framework provided.

But, if you wrote (or at least have access to the source code of) the code which is calling pop() , you have the option of catching the exception and dealing with it however you want. For instance, if you'd like to display just the error message and not the full stack trace, you can do something like this:

    try {
        pop();
    } catch (ArrayIndexOutOfBoundsException ex) {
        System.err.println(ex.getMessage());
    }

Of course, regardless of anything else you read here, be sure you understand the requirements of your assignment an follow them to the letter.

Requirements for invocation of pop method

  1. can be invoked even if the stack is empty
  2. should not throw exception
  3. method signature can be changed

Approach with Optional

import java.util.Optional;

public class StackTest {

    public static void main(String[] args) {
        Stack<Integer, Optional<Integer>> stack = new MySafeIntegerStack(1);
        System.out.println(stack.push(1));
        System.out.println(stack.push(1));
        System.out.println(stack.pop().get());
        Optional<Integer> popped = stack.pop();
        if (popped.isPresent()) {
            System.out.println(popped.get());
        } else {
            System.out.println(popped);
        }
    }

    interface Stack<U, V> {

        boolean push(U value);

        V pop();
    }

    static class MySafeIntegerStack implements Stack<Integer, Optional<Integer>> {

        private int maxStackSize, topOfStack;
        private int[] stack;

        public MySafeIntegerStack(final int maxStackSize) {
            if (maxStackSize <= 0) {
                System.out.println("Stack size should be a positive integer.");
            } else {
                this.maxStackSize = maxStackSize;
                topOfStack = -1;
                stack = new int[maxStackSize];
            }
        }

        public boolean push(final Integer val) {
            if (topOfStack == maxStackSize - 1) {
                System.out.println("Cannot push! Stack is full.");
                return false;
            }
            stack[++topOfStack] = val;
            return true;
        }

        public Optional<Integer> pop() {
            if (topOfStack == -1) {
                System.out.println("Cannot pop! Stack is empty.");
                return Optional.empty();
            } else {
                return Optional.of(stack[topOfStack--]);
            }
        }

        public int size() {
            return (topOfStack + 1);
        }
    }
}

Note

  • Assuming stack has to be implemented using array(and not list), generic types can not be abstracted further. (array creation is not possible for generic types)
  • Another implementation can be added to throw exception incase of invalid pop() and push() invocations

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM