Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Difference between throwing an Exception and catching and rethrowing Exception

I'm confused as to what the beneift would be in catching and rethrowing an exception versus just throwing it in the first place.

For example

private void testMethod() throws Exception
{
    //some bad code here
} 

versus:

private void testMethod() throws Exception
{
    try
    {
        //some bad code here
    }
    catch (Exception e)
    {
        throw e;
    }
} //end testMethod()

Is this to preserve the stack trace of the error message? I tried setting up an example, but didn't see any different output between the two.

Thanks for the help.

like image 528
Michael878 Avatar asked Mar 08 '12 00:03

Michael878


People also ask

What is the difference between throwing an exception and catching an exception?

Q #1) When to use throws throw VS try-catch in Java? Answer: The “throws” keyword is used to declare the exception with the method signature. The throw keyword is used to explicitly throw the exception. The try-catch block is used to handle the exceptions thrown by others.

What is throwing and catching the exception in Java?

Throwing an exception is as simple as using the "throw" statement. You then specify the Exception object you wish to throw. Every Exception includes a message which is a human-readable error description. It can often be related to problems with user input, server, backend, etc.

What is Rethrowing an exception?

If a catch block cannot handle the particular exception it has caught, you can rethrow the exception. The rethrow expression ( throw without assignment_expression) causes the originally thrown object to be rethrown.

Can I catch and throw the same exception in Java?

Customers often have general catch blocks in Servlets, MDBs, EJBs and other core components where they catch all un-handled exceptions and re-throw them as new Exceptions, adding application specific debugging information or auditing information.


2 Answers

There is no difference in behaviour between your two code samples. (In particular, stacktraces are recorded when an exception is created, not when it is thrown, so a rethrown exception will still have the original stack trace). Usually, people therefore use the simpler idiom.

That is not to say rethrowing doesn't have its uses. For instance, if you wanted to handle all exceptions except FooBarExceptions, you could write:

try {
    // bad code 
} catch (FooBarException e) {
    throw e;
} catch (Exception e) {
    e.printStackTrace();
}

Or if the decision to handle an exception is more involved than simply checking its type, you can simply catch it, and rethrow if it turns out you can't handle it:

for (int attempts = 0; attemps < 6; attempts++) {
    try {
        return crankyMethod();
    } catch (Exception e) {
        if (fatal(e)) {
            throw e;
        } else {
            // try again
            continue;
        }
    }
}

It is worth noting that when people say rethrow, some mean to throw a different exception, as in the following example:

for (int i = 0; i < array.length; i++) {
    try {
        process(array[i]);
    } catch (Exception e) {
        throw new RuntimeException("Could not process element at index " + i, e);
    }
}

The advantage of this pattern is to decorate the original exception with additional information that might be relevant (in the above example: what data could not be processed). Note that the original exception is passed to the constructor of the new one, so its stack trace is not lost.

like image 179
meriton Avatar answered Sep 29 '22 06:09

meriton


As others have said, in your example there is no difference, and the 2nd form should be avoided.

The only place where it sometimes makes sense is where you need to catch some exceptions, and let others get thrown upwards. Because Java's exception handling syntax is limited, sometime you might do this:

try {
   somePieceOfCode();
} catch( RuntimeException e ) {
   throw e;
} catch( Exception e ) {
   handleException(e);
}

This is sometimes done if somePieceOfCode throws a number of different checked exceptions that don't have a common base class (other than Exception) but need to be handled in the same way. You might not want to just catch Exception because that would also catch things like NullPointerException, and you might prefer for those exceptions to bubble up as-is.

This code will let all RuntimeExceptions bubble upwards, but handle all other exceptions.

This idiom is little unusual, and not everyone likes it, but you might see it in some places.

like image 29
Tim Avatar answered Sep 29 '22 07:09

Tim