2004-05-11

All Exceptions are RuntimeExceptions

If Java had a well-designed exception hierarchy, with the this need not be so. But as it is, any program that uses a combination of external libraries has to deal with several different exception hierarchies, and with nested and hidden exceptions, and so must be prepared to both handle and throw RuntimeExceptions. I wish it were not so. I wish that Exception were partitioned into RuntimeException and DeclaredException, so the idiom
 try {
  ... stuff
 } catch (Exception e) {
  if (e instanceof RuntimeException) {
   throw (RuntimeException)e;
  }
  ... deal with resource problem
 }
could simplify to
 try {
  ... stuff
 } catch (DeclaredException e) {
  ... deal with resource problem
 }
The trouble is that exception types, unlike other types, are global, because they cross boundaries. It is a good thing to invent new types (classes) to make concrete the kinds of things your new program can do; each Java package is a domain-specific language. But it is a bad thing to invent new exception types, because that structure affects the structure of every program that uses your package. Much better to have a common, well-designed exception hierarchy so that everyone knows, without new learning, which exceptions to expect. Here's one criteria for a well-designed exception hierarchy: when writing a program, it is obvious what kinds of exceptions should be thrown, and when the standard classes will serve, and how to extend them if more detail is needed. The present hierarchy does not come anywhere near that standard. It has very many too many classes, not enough nesting, too many ambiguous exceptions, and unclear rules on when system exceptions should be re-used, extended, or avoided. It obviously "just grew", which leaves all other Java programs to muddle through on the same wobbly foundation. Part of this muddle is the use of RuntimeException to pass information through a library or middle layer, or to wrap an exception that was unanticipated by the library designer. If there were a common exception hierarchy, the library designer would be much more likely be able to anticipate what exceptions would legitimately arise in the use of the library. Not universally, however; a general-purpose interface (like Runnable, to pick an extreme case) must cope with arbitrary exceptions. This forces any declaration up to the top of the hierarchy; in fact, either up to Exception, or (as proposed above) to a sensible partition of Exception into RuntimeException and DeclaredException. It's possible, but too hard, to set a handler for exceptions. The way to do it nowadays is to extend ThreadGroup, overriding the uncaughtException method; clearly not an everyday sort of thing to do.

Comments: Post a Comment

Subscribe to Post Comments [Atom]





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]