1

I'm using a try-catch block to catch any exceptions that might be thrown when I run certain methods on a stack. My code for the pop method looks like this:

public T pop() { T temp = null; try { temp = first.data; } catch(Exception e) { System.out.println("Invalid operation on an empty stack"); } first = first.next; return temp; } 

When I run the program the exception is caught... my terminal produces this: (menu choice 'd' is the pop method)

Please enter a menu choice: d

Invalid operation on an empty stack Exception in thread "main" java.lang.NullPointerException at MyStack.pop(MyStack.java:58) at StackTest.main(StackTest.java:52)

so I think my exception is being caught since it prints "Invalid operation...", but my program also terminates when the exception is thrown. Any help?

2
  • 1
    You may have swallowed the first exception from first.data, but what if first was null? Then first.next would throw another NPE Commented Jan 22, 2015 at 22:13
  • I am almost sure your first is null Commented Jan 22, 2015 at 22:16

4 Answers 4

2

We have learned a very valuable lesson today: don't catch Exception without good reason.

The problem here is that first is coming back null, so we're going to throw that exception once we try to dereference it.

Let's look at it from a different angle. If first is null, we know we can't pop anything, so we should be throwing the exception instead.

public T pop() { if(first == null) { throw new EmptyStackException("Invalid operation on empty stack"); } T value = first.data; first = first.next; return value; } 
Sign up to request clarification or add additional context in comments.

3 Comments

I originally had your exact code, but by throwing an exception won't my program automatically terminate? I'm trying to make it so the program will still run after displaying the error message.
Catch it a layer up. That is to say, catch it when you try to pop the value (have your try...catch block wrap the execution of pop). There's nothing from the stack's perspective that it can do if it doesn't have any data in it and you want to take data from it.
I instead created my own exception that extends the runtimeexception and put my error message in there while throwing the exception instead of the try-catch block. worked perfectly.
1

Seems like there's another exception being thrown, after your catch block. It is very likely that first is null. That causes the catch block to be executed (because first.data is a null pointer exception), but it also causes another null pointer exception at

first = first.next; 

Thus you have an uncaught exception. How you tackle this is up to you; it's more of a design decision than a correctness one.

The simplest and probably correct option is to do all of your modification inside the try block, so if something goes wrong you don't resume operations that probably won't work.

public T pop(){ T temp = null; try{ temp = first.data; first = first.next; } catch(Exception e){ System.out.println("Invalid operation on an empty stack"); } return temp; } 

Of course, the try..catch construction isn't really appropriate here. A much more succinct way to write the same method would be:

public T pop(){ if(first == null) return null; //By virtue of reaching this point, first is necessarily non-null. T temp = first.data; first = first.next; return temp; } 

But if the goal was to experiment with try..catch use my top answer.

Comments

1

first is clearly null based on your output. Now, you're catching the NullPointerException that arises from temp = first.data, but not the one that arises from first = first.next (since that assignment is not enclosed with a try block):

public T pop() { T temp = null; try { temp = first.data; // <-- you catch the exception thrown here } catch(Exception e) { System.out.println("Invalid operation on an empty stack"); } first = first.next; // <-- but you don't catch the one thrown here return temp; } 

In general it's a very bad idea to catch a NullPointerException; explicitly check for null beforehand.

1 Comment

It's also a very bad idea to work with nulls in the first place. Consider Optional<T> (in Java 8) or similar datatypes in libraries such as functionaljava or Guava
0

It's highly likely that your first is null.

Try this code instead

public T pop() { T temp = null; try { if (first != null) { temp = first.data; first = first.next; } } catch(Exception e) { System.out.println("Invalid operation on an empty stack"); } return temp; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.