winsticknova
winsticknova

Reputation: 375

Try-Catch block termination

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?

Upvotes: 1

Views: 2742

Answers (4)

Makoto
Makoto

Reputation: 106498

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;
}

Upvotes: 2

arshajii
arshajii

Reputation: 129577

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.

Upvotes: 1

Aify
Aify

Reputation: 3537

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;
}

Upvotes: 0

Mshnik
Mshnik

Reputation: 7042

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.

Upvotes: 1

Related Questions