Wednesday, August 10, 2011

JDK 7: Multi-catch and final rethrows

Another neat feature in JDK 7 is the multi-catch feature for exception handling.

If you have code that reads like:

try {
    doSomething();
} catch (ParseException pe) {
    logger.error("Parsing Failed", pe);
    throw pe;
} catch (IOException ioe) {
    logger.error("IO Failed!", ioe);
    throw ioe;
}

It can now be written more concisely as follows:

try {
    doSomething();
} catch (ParseException | IOException e) {
    logger.error("Some exception", e);
    throw e;
}

This really cuts down the boiler plate code for handling the individual exceptions, especially if all you are doing is to simply log and re-throw it. The problem however manifests more generally when we see code that doesn't bother to catch the individual exception but handles it using a generic Exception type.

try {
    doSomething();
} catch (Exception e) {
    logger.error("Some exception", e);
    throw e;
}

In this case the calling method must handle the more generic Exception type and we lose the specific exception. In JDK 7, we could add a keyword, final, to the catch block and specify that the specific type of exception be thrown instead.

try {
    doSomething();
} catch (final Exception e) {
    logger.error("Some exception", e);
    throw e;
}

The "final" is optional, however it adds clarity that the specific exception will be thrown instead of the generic Exception. Here is a more rounded example that explains this:

public class TryCatch {
    public static void main(String ... args) throws Exception {
        doSomething();
    }

    private static void doSomething() throws IOException, ParseException {
        try {
            if (Math.round(Math.random()) %2 == 0) {
                doStuff();
            } else {
                doSomeOtherStuff();
            }
        } catch (final Exception e) {
            out.println("Omg, there was an exception!");
            throw e;
        }
    }

    private static void doStuff() throws IOException {
        throw new IOException("Oops, IO failed!");
    }

    private static void doSomeOtherStuff() throws ParseException {
        throw new ParseException("Uh no, Parsing failed!", 0);
    }
}

Another neat-feature that I think should have been added a long time ago.

No comments:

Post a Comment