Exceptions, part 4
Tuesday, November 30th, 2004Yes, there is even more to say about exceptions. So after part 1, 2, and 3 in the series, here is part four.
Checked vs. Runtime
In Java, there is a distinction between exceptions that need to be caught or declared in a throws clause, and those that do not. The former are named checked exceptions; the latter runtime exception, since they all inherit from the java.lang.RuntimeException class. If you do not catch a checked exception or declare it in the throws clause of the method, you will get a compiler error.
When the specs of the first version of Java were written, this seemed like a very good idea. And, at first sight, it still does. What could be better than to have a compiler error when you forget to include error handling for the methods you use? Actually, there are two things wrong with it.
Too many exceptions
Image that you are integrating four or five systems, and that each system throws about ten different exceptions. When the compiler tells you that there are a gazillion exceptions that need to be handled, what is the quickest (and thus most likely used) way to solve these errors?
- Catching
java.lang.Exceptionand ignoring the result. This is not an option, since we just learned that is not a good thing. - Adding
throws Exceptionto the signature. This also is not an option, since it does not offer any specific information. It just says: something could go wrong here. I don’t know what could go wrong, but don’t say I didn’t warn you! - Catching
java.lang.Exceptionand wrapping the result in a runtime exception. This is the best possible solution to this problem.
As it turns out, checked exception become such an nuisance that most developers use one of these three workarounds.
Breaking interface changes
Martin fowler was right when he said that [a published interface] is more public than public.. If you publish an interface, and later on add more exceptions, you break the API and your users do not tend to like that. As an alternative, you could decide to throw only runtime exceptions.
Now, the clever reader has noticed that the common solution to the two issues is to use the runtime exception. Now wonder Anders Hejlsberg, the lead C# architect, decided not to copy this particular feature from Java. He did a pretty good job copying the rest though.