Checked Exceptions are Waste

I can’t get no satisfaction, I can’t get no satisfaction
‘Cause I try and I try and I try and I try

(I Can’t Get No) Satisfaction – The Rolling Stones

Checked vs. Unchecked Exceptions

It’s a controversial subject; searching Google for checked versus unchecked exceptions reveals a lot of heated discussions both for and against Checked Exceptions.
Charles Lowell has a particularly succinct (and possibly NSFW) view

My view is similar. I can almost see a situation where I would like to ensure that exceptions are dealt with in a certain way, but it doesn’t quite reach as far as using checked exceptions.

Noisy IDEs

I think my issue is largely to do with the way that the IDEs (and compilers) deal with checked exceptions.
In Eclipse, if a method throws a checked exception, then auto-fix suggests two options; “Surround with try/catch” and “Add throws declaration to method”
I particularly have a problem with the second one. The further you get away from the source of the exception, the less likely you are to deal with it in a useful way. Not dealing with the exception is a reasonable option, but why does everyone in the call chain need to know about an exception that someone in the lower levels didn’t care enough about to handle?
Using unchecked exceptions gives us the choice to handle or propagate the exception, without polluting the higher levels with knowledge of unhandled exceptions.

The default Eclipse template for try / catch is to catch the exception and print the stack trace. This isn’t really handling the exception, it’s ignoring it (even if we’ve logged it). There is no way to know if this is an acceptable default without understanding the underlying code. Unfortunately, if we are leaving it as the default we probably don’t understand the underlying code (yet).

An alternative to Checked Exceptions
One of the nice things about checked exceptions is that they let you know the types of exception you can get. You get the IDE auto-completion and compiler checking.
A checked exception is essentially saying, “You might get this exception, and I insist that you deal with it in the way that you feel is most appropriate”
How can we continue to do this, and at the same time prevent boiler-plate or unnecessary pollution?

Something that I’m thinking about (but haven’t had the need to implement yet), is the concept of an ExceptionHandler class. This is an ideal place for Java Generics to come into play.
For example:

public void someCodeThatMayThrowAFileNotFoundException(String fileName, ExceptionHandler<FileNotFoundException> exceptionHandler) {
try {
open(fileName); // throws FileNotFoundException
}
catch (FileNotFoundException e) {
exceptionHandler.handleException(e);
}
}

By coding in this way, we can provide sensible default actions, such as:

// The Generic stuff has not been checked and is for illustration purposes.
// Let me know if I need to correct it :-)
public class PropagatingExceptionHandler extends ExceptionHandler<T extends Exception> {
public void handleException(T exception) {
throw(exception);
}
}

public class LogAndIgnoreExceptionHandler extends ExceptionHandler<T extends Exception> {
public void handleException(T exception) {
exception.printStackTrace(); // or log4j equivalent
}
}

This reduces the try / catch noise, gives us the compiler checking and type completion, and explicitly details the strategy that we are using for handling the exceptions for this part of code.

I’m open to someone showing me a really good use of checked exceptions, but for the time being, I won’t be using them.

4 thoughts on “Checked Exceptions are Waste”

  1. The reason Java checked exceptions are a pain is because, like everything in Java, they didn’t quite finish when they adopted the idea. In Modula-3, there is a FATAL pragma which meant that you can declare that you don’t know how to handle a checked exception within a given scope. If such an exception occurs then the program fails. It’s so simple but it makes all the difference to the usability of checked exceptions.

    The point of checked exceptions is that it allows me to know all the paths out of a chunk of code, otherwise I have to assume that any method call can fail and over-protect the logic.

  2. I always change my Eclipse default catch clause to:
    throw new RuntimeException(e);

    Don't add and exception to the throws clause unless it will make sense to the caller. If it's a case that should never happen, or cannot be handled, wrap it in a RuntimeException, which effectively converts the checked exception to an unchecked one.

    I don't see why an “ignores” clause couldn't be added to Java methods to do this wrapping automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>