Friday, June 19th, 2009

Exceptional Value?

What is the value of exceptions in programming languages? Great in many ways. Does anybody remember the clunky longjmp? Or the terrible programming style where a return code must be examined after every function call? Exceptions are invaluable to keep error handling from messing up the logic of your code.

So exceptions are good. If something is good, isn’t more of the same better?

Java took exceptions to a new level. The last thing the Java compiler does is checking that the right exceptions are declared in the right places. Just when you think your code compiles clean you have to dive into tracing the exception flow. Not a bad thing in itself, but especially after I got into Groovy programming I’m beginning to suspect the effort is spent on a largely artificial problem.

Java has checked and unchecked exceptions. Unchecked exceptions do not have to be explicitly caught. They are typically thrown by bugs in your code.

Checked exceptions in Java have been debated from the start. The idea is that a method signature not only informs you about the parameters of the method, but also tells you the exceptions it may throw. It may seem like a disciplined extension of Java’s strong typing.

As a result an interface defines not only the data that goes in and out of methods, but also the ways in which the module may break down. The purpose of interfaces is to hide the implementation. Exceptions defeat this purpose because they inherently reveal implementation details. If a module stores data in the file system every method will throw java.io.IOException. If you change the implementation to use a database every method will throw java.sql.SQLException.

You don’t want such implementation details to leak out of a module. This means that every significant Java module should convert their exceptions to either custom exception types or to (unchecked) java.lang.RuntimeException that doesn’t have to be declared. The latter solution is not as bad as it may sound. Exceptions in Java may be chained, so all information about what happened may be kept.

Not all exceptions imply total breakdown. Parsing an input string is a good example of situations where you can do something meaningful about an exception. Throwing an exception is the natural way to signal a syntax error. To me it’s strange that methods like java.lang.Integer.parseInt() throw an unchecked exception. On the other hand, java.text.DateFormat.parse() throws a checked exception.

Most checked exceptions, like IOException, are things you can’t do much about. Of course the application must react, but in almost all cases the problem must be fixed outside the application. I’m afraid the time spent designing Java exception flows is largely wasted.

Comments are closed.