Den of Antiquity

Dusting off old ideas and passing them off as new.

Never Create a RuntimeException

Don’t worry, this isn’t a post about “checked exceptions”.

Of course the post-title isn’t an iron-clad rule, but you really don’t have any excuse to have the following code in your application.

throw new RuntimeException("innocuous message");


You can catch them, and throw them again if caught.  But RuntimeException is just meant to be a super class for you to extend from for your own exceptions.  In any error situation, there is always a more application exception class that already exists. Or you can consider creating one for your app.

If the issue is with something passed into the method, you can always throw the very popular IllegalArgumentException.  Or, In the absolute worst case, you can always just throw a new IllegalStateException(), as that’s the most generic RuntimeException.

There are even handy libraries to replace your state and argument checking boiler plate code.  See Preconditions from Google Guava (formerly google collections), which is far more readable.
import static com.google.common.base.Preconditions.*;

public Object getCachedValue(Identifier id) { 
    checkNotNull(id);
    Object value = cache.get(id);
    checkState("id not cached",value != null);
    return value;
}

Even in test code, you could probably throw an AssertionException instead, if your not using
asserts to test the state anyways.

A personal favorite of mine is UnsupportedOperationException, instead of a custom UnimplementedFeatureException.  Whenever code tries to do something that isn’t _supposed_ to work (yet).  Because, frankly, I’m quite often lazy, or just too busy to write everything at the start.

Furthermore, when you create your own RuntimeExceptions, consider sub-classing IllegalStateException or some other reasonable exception.  These super-classes, while adding no functionality, give hints to other developers about the intrinsic meaning behind these new exception their seeing.

Comments

Marian
That is one fascist thinking, I'd say :D
pholser
Right on. IMO, Throwable, Exception, RuntimeException, and Error needed to be made abstract.
Marian
Thanks for the opinion.
But I still do not see any point in subclassing RuntimeException. Does it help anything except for the code to look prettier? Unchecked XYZMySpecialException may in my experience create much more confusion than simple RuntimeException. You may end up with your junior programmers simply catching and ignoring everything subclassed from Exception in that piece of code. Or make them attracted to throw them in other places it was supposed to be thrown.
That it was designed just to be subclassed? Who says? Would not it be abstract then?
The only point of subclassing unchecked exception is to provide some extra information for the exposed class/method's user. Unless you are trying to collect some runtime statistics everyone needs to look at the exception message anyway.
I do throw IllegalArgumentException-s in case an input argument is wrong. But that is the only small sacrifice I am willing to take with this. Any RuntimeException should in my view represent a truly exceptional and and unexpected situation. And which should really not happen in production.
Your arguments, in my opinion, go well for checked exceptions. Throwing whose has its non-academic purpose in production code too.