Darren Hobbs: Checked Exceptions Don't (always) Suck. I agree with Darren's statement that checked exceptions are misused a lot. As a matter of fact, they're misused so much that I've come to the conclusion that, while great in theory, they do indeed suck in practice.
If you have a team of experienced and disciplined Java developers that truly understand how exception handling is supposed to work in Java, the distinction between checked and unchecked exceptions is great and really helps develop robust applications. Unfortunately, real-world teams typically don't work that way and many mistakes are made that turn the benefits of checked exceptions into a disadvantage.
Here's a list of the exception handling mistakes I've seen made most often:
RuntimeException
descendants, but instead make everything checked. This puts a huge burden on the caller to deal with all these exceptions. A method should only be declared to throw an Exception
if its caller should be forced to (and can be expected to be able to) handle this exception. Program bugs on the other hand (like a method being called without its preconditions being met) should throw RuntimeExceptions
.
catch
-block in to satisfy the compiler. Then when this exception subsequently does happen, it is ignored and will probably cause the application to fail somewhere else. Trying to find the source of this other failure will then oftentimes prove to be a real nightmare.
System.out
in a catch
-block is almost just as bad as ignoring it with an empty catch
-block. This may help during development, but who watches the console in production? And even if someone does watch it 24/7, how acceptable is this kind of error-handling really to your users?
Exception
, just to exit a method with a null
return value. This is bad as it oftentimes results in a NullPointerException
elsewhere.
catch(Exception e)
clause. This is often done by developers that are forced to deal with many different types of exceptions. The problem with this is that different exceptions tend to need to be handled differently. A NullPointerException
for instance would need another handler than a SQLException
. Also, by adding a generic catch(Exception e)
, you also automatically handle any future exceptions that may be thrown by new code being added to the try{}
block later. This nullifies the main advantage of checked exceptions: being forced to handle them.
throws
this exception.
Throwable
class has built-in support for wrapping a cause-exception. If you use an older JDK, keep a reference to the cause-exception in your exception class and override printStackTrace()
(all three variants) to also print the stack trace of the original exception.
RuntimeExceptions
from an EJB without realizing the implications this has on the current transaction. When using Container Managed Transactions, RuntimeExceptions
will automatically mark your current transaction for rollback, which is oftentimes not what you want. They also get wrapped in an EJBException
by the container, preventing the client from easily being able to catch specific RuntimeExceptions
.
The net result of all these potential problems is that Java's exception handling mechanism is typically poorly implemented, leading to fragile applications that are hard to debug when things go wrong.
Do I think the C# approach of making all exceptions unchecked is perfect? No I don't. There are clearly benefits to being able to force a method caller to deal with certain Exceptions. Unfortunately the theory of checked exceptions works better than the typical implementation of them.
I agree with all these points, though with JDK 1.4, wouldn't you rather assert(false) than rethrow something as a runtimeexception if there really is a bug (something a caller would never be expected to handle - and a situation where you want your system to fail as fast as possible)?
Posted by Steve Conover at February 27, 2003 12:09 PMI didn't mean to say just assert false, you might want to provide some helpful message to the assert...or a printstacktrace would probably do in that situation too.
Posted by Steve Conover at February 27, 2003 12:11 PMFor potential program bugs that are internal to your methods, I agree that using assert is oftentimes better than throwing a RuntimeException. You need to be careful with this though as assertions can be turned off (so your application may not check them), and failed assertions throw an Error, which may end up killing your entire application (since catch(Exception e) won't catch them) which is typically not what you want.
When checking method preconditions on the other hand, specific RuntimeException descendants are preferred.
See http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html#usage for deeper coverage on when assertions should and should not be used.
Posted by Luke Hutteman at February 28, 2003 1:14 AMChecked Exceptions Are Important
Luke states that he has come to the "conclusion that, while great in theory, they[checked exceptions] do indeed suck in practice". I have to completely disagree with him. I tend to agree with Darren.
Exceptions
Blog Explosion! As far as I can tell, it started with this article by Bruce Eckel. Darren Hobbs responded, which caused Luke Hutteman to comment. Les Stroud disagrees, and so Luke has to answer. Now, Gosling has responded, and here...