Declared Runtime Exceptions: The Best of Both Worlds?
Exceptions on the Java platform are familiar enough, but there's no universally agreed way to design an exception system at the application architecture level. TheServerSide recently hosted a discussion about declared runtime exceptions, so let's take a look at the idea here.
The following is based on Declared Unchecked Exception: The Best of Both Worlds, published on the Hacking Architect blog.
The Basics
- The application exception hierarchy inherits exclusively from
java.lang.RuntimeException, so all its exceptions are runtime exceptions by definition. - Every application exception is declared in the
throwsclause of any method that can throw it. - Handle ordinary runtime exceptions like
java.lang.NullPointerExceptionin the usual way, without the explicit declaration used for application exceptions.
public class MyORMException extends RuntimeException { ... }public class ObjectNotUniqueException extends MyORMException { ... }... // define other exceptionspublic class MyORMSession {public void commit() throws ObjectNotUniqueException,DatabaseException, DataSecurityException;}What This Means
Let's see what this approach looks like in code.
- Even though an exception appears in the
throwsclause, client code is free to leave it unhandled because it is a runtime exception. - Changing the
throwsclause in the future does not force you to change client code. - The method declaration tells us which application exceptions can occur and which ones we might want to handle.
Trade-offs
Of course, this approach also has a downside for our code.
- We lose static checking. The compiler and the IDE will give no warning about an unhandled exception.
- We have to keep the
throwsclauses of the relevant methods up to date ourselves.
Despite its clear benefits, the approach has a few side effects. I wouldn't use it for the entire application exception hierarchy. A hierarchy of declared runtime exceptions suits parts of the system where the exceptions are systemic, such as the database layer. Application logic is a poor fit. Checked exceptions make sense there because the logic itself may require an exceptional situation to be handled explicitly, for example when a transfer between accounts exceeds a limit.
My advice is to use this approach sparingly. If you've adopted it, I'd love to hear about your experience in the comments.
Related articles
Related CZ Podcast episodes
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi and Filemon discuss Java 6 and web application frameworks. · Czech audio
- #1 · Vývojová prostředí v Javě
The first CZ Podcast episode looks at Java development environments. · Czech audio