Exceptional Java - Checked exceptions are priceless… For everything else there is the RuntimeException
Of course the checked exception as a tool can be abused and misunderstood. Nobody can stop me to hit myself in the head with a hammer if I want to or if I don’t know any better. The same is true for the unchecked exceptions.
The danger I see with an “all unchecked” decision is in the human nature. People tend to not read documentation. Sometimes it is because of the pressure and constraints and sometimes it is because people are lazy.
Checked exceptions are for programmers what Jiminy Cricket is for Pinocchio, the voice of his conscience. In some languages the voice is tiny and begs for attention. In Java the voice is loud and demands attention.
To sum up what I think about checked exceptions here is my answer to a comment on one of my previous posts on the subject:
“I agree that checked exceptions are domain exceptions. But the domain changes with code level. For low level code that deals with files IOException is a domain exception. For code that deals with a database SQLException is a domain exception. In my opinion if I try to read from a file and the file is not there I should get a checked exception because this situation can be recoverable. True, sometimes it isn’t. But most of the time it is or it should be. I don’t want my thread to die and the whole server to crash because some pressured programmer forgot to deal with an exception because the compiler didn’t force him to do so. I honestly believe Java is one of the most popular and productive languages because of checked exceptions. Because it takes into account the reality of a very constrained software industry (deadlines anybody?) and the reality of human nature (I don’t do what I am not forced to do).
I fully agree that checked exceptions are abused and sometimes because of poorly designed APIs they are a pain to deal with (just look at the reflection APIs). But I think unchecked exceptions can be abused as well and, in my opinion, their abuse is even more dangerous.
I actually think the answer is in education. Senior programmers leading projects should take the time to think about the exception handling policy in their projects and then take the time to educate younger programmers working for them.
I tend to try to deal with an exception as early as possible at the point where I can make an educated decision if I can recover or not. Also in APIs, internal or external, I present only domain exceptions (LoginFailedException) with lower level exceptions embedded as causes. This way the caller of my API can decide what to do and at what level to look into the problem. I can imagine a piece of code that fails and ends if the login failed while other piece of code might decide to try to login into another repository - unrecoverable vs recoverable”
Of course there are other opinions on the subject. Jakob Jenkov wrote a nicely documented article (Checked or Unchecked Exceptions?) with many interesting links on the subject. Here is my dzone.com comment on his article:
“I guess one’s experience explains the attitude to exceptions. If you write code where the cost of failure is low you don’t want the checked exceptions to mess with your nice logic. Also if you want to write a prototype you don’t care much about the failure conditions. In these situations you can decide that failing the whole application is fine. If you have the luxury of being there and watch the application crash, analyze the log files and fix the code you are fine with unchecked exceptions. The same is true for the GUI applications most of the time. The whole application can fail or the requested operation can fail without much commotion.
On the other hand if you write code that has to run unattended on the server side, in mission critical scenarios, for banks, military and governments, hospitals, telecom and so on then you don’t have that luxury. You have to imagine in advance all failure scenarios and make the software survive at runtime. And not only survive, but actually recover as well as possible. And here checked exceptions are priceless… For everything else there is the the RuntimeException!”
I think that many factors influence one’s opinion about checked exceptions:
- experience
- personality
- nature of the project
- project coding culture, ecosystem and environment
Let’s make an effort and imagine…
… who might like checked exceptions
Based on this I imagine the kind of people who like checked exceptions might be:
- people working on big projects where development takes years and where the programmers move around a lot
- people who think that finding problems at runtime is more expensive than finding them at development/compile time and who don’t have full control over what is happening during development
- programmers working on projects where people lives are at stake
- people working on distributed complex projects
- server applications developers who know their code has to work unattended
… who might hate checked exceptions
- lone gunners, excellent programmers who work alone or in small controlled groups and know exactly what they do and why
- consultants who might be part of the above category (and also can create a new revenue stream from all these uncaught exceptions - just joking)
- people who work on software that can fail without a major impact
- prototype code writers who are only interested in proving a concept
- GUI and interactive applications developers who have the luxury of catching every exception in an outer loop and displaying a message to the user (who is clueless)
And then people who hate checked exceptions for the wrong(ish) reason:
- people who want their code to look pretty for demo purposes (book writers, teachers, bloggers :))
- beginners who find the concepts hard to deal with without realizing the problem still exist even if the proposed solution changes
One word about teachers and book writers. They form opinions so they have to be careful what ideas they promote. Most of the students are not going to be book writers and teachers but programmers on real life projects. The purpose of writing a neat example in a book just to prove a concept is not at all the same with the purpose of writing solid code for deployment to customers.
In the end I will just express my curiosity on what will happen to Hibernate who moved to unchecked exceptions in version 3. While I am an admirer of Hibernate and the team who creates it, I kind of expect threads to start to die in applications servers around the globe. Or I might be wrong. Maybe the entry level is so high that only programmers who fully know what they are doing can use Hibernate
This post is part of a series on exceptions:
- Thoughts on Java exceptions
- Some exceptions are more equal than others
- Less than perfect exceptions hierarchy
- Checked exceptions are priceless… For everything else there is the RuntimeException
- Design the failure case - Part 1
- Design the failure case - Part 2
- Exception design relativity
- Bad advice on exceptions from Joel





There is another category of developers “who may hate checked exceptions”:
Developers working on transactional systems in which there is nothing else to do in the face of failure, than to abort the current transaction (rollback etc).
In my experience, many larger server systems fall into this category, GUI or no GUI.
Deciding to abort the transaction and cleanup equates to catching the exception in the appropriate context. Checked or unchecked you still need to catch it where it makes sense. The advantage of checked exceptions is the fact that you cannot ignore them by mistake.
I have yet to find any proponent of checked exceptions who could give a straight answer to this question of mine:
Would you be OK with it, if Java disallowed the return value of a method to be ignored, for instance, if we were syntactically forbidden from writing:
anInputStream.read();
and had to do:
int data = anInputStream.read();
The second part of that question is, how is that different from forcing a checked exception to be dealt with in the immediate calling context?
@Jing Xue
Interesting parallel but I don’t think it is the same thing. The return value can have various meanings. The return value is used usually for the success path but sometimes as in C/C++ as the error value. Also it is used in coding patterns like call chaining. Due to the variety of the usage I don’t agree with its usage to be enforced by the compiler.
On the other hand when you work with exceptions you have a choice: checked or unchecked. I think the choice is good. If I design an API and I consider I should force the calling code to treat my exception cases I should be allowed to do so. As a user of APIs I always have the opportunity to transform exceptions from checked to unchecked by wrapping them.
So the difference in my opinion is in the fact that with exceptions you already have a choice. Another difference is in the purpose of the two language features. Return values are meant to represent the normal execution path while exceptions are meant to represent the failure path. I think features should be used in their spirit. A failure should dealt with as fast as possible in my opinion as this increases the chances of recovery.
@Daniel,
First let me post the link to a blog entry I wrote a while ago that elaborates my argument:
http://www.digizenstudio.com/blog/2007/07/17/checked-exceptions-and-alternate-business-flows/
Now to respond to some of the points in your comment in particular -
“If I design an API and I consider I should force the calling code to treat my exception cases I should be allowed to do so.”
But you can’t really force them, can you? Not when they can, as you pointed out, wrap and/or re-throw the exception right away.
So in the end we have this language feature that can not really _force_ the calling code to deal with the exception, but rather really just _warn_ the calling code that an exception could be coming. And the calling code has to go out of way - all the pesky try/catch/throws - to deal with just the _warning_.
“Return values are meant to represent the normal execution path while exceptions are meant to represent the failure path. I think features should be used in their spirit.”
True. However, there is this big gray area between what’s clearly ‘normal’ and ‘failure’. Some people think AccountNotFoundException is a failure, while some others think only DatabaseIsNukedException is. I’m sure you have worked on code that effectively uses exceptions as alternate return values.
“A failure should dealt with as fast as possible in my opinion as this increases the chances of recovery.”
Could you please give a concrete, real life example where a failure would only be recoverable within the immediate caller, but no longer so once it gets re-thrown to the caller of the caller?
OTOH, I would argue that in many cases the immediate caller is not necessarily in the best position to deal with the exception. For instance, when a SQLException gets thrown from the driver, and caught by the DAO (the immediate caller), we usually would not want to handle it there. Instead, we would want to deal with it in the service layer by, e.g., rolling back the transaction. So why making it a checked exception, only to have the DAO either re-throwing it or wrapping it with some vaguely named DataAccessException?
Hi! Excellent series!
I was looking for this kind of info for some time, since at my job I’m involved in a project that has no estabilished guidelines regarding exceptions and in many places their handling is badly abused. I’m looking for ways to recover from this and fix it.
This topic is very important: while many books teach young developers what exceptions are, they do not provide deeper understanding of them nor best practices to follow. I think it would be great if you gave a little info what language creators and book writers (J.Gosling, B.Eckel and others) have written on the topic - just for comparision and further discussion.
Some questions:
1. Should we reuse exceptions from standard java APIs or provide our own?
2. How much chaining is too much?
3. How to investigate inner exceptions (root causes) in a clean and good way? (i.e. avoiding if-instanceof cascades and such)
@Jing Xue
I read your post and I see you have a formed opinion. It is not my intention to change your opinion :). But, to continue the debate:
- Indeed I cannot force them to “treat” the exception. But I can force them to make a conscious decision to treat or ignore it. You call the try/catch blocks “pesky” but on the other hand I am not concerned with how pretty the main success path looks in text. I am more concerned with people forgetting to treat error conditions.
- Wrapping is a good technique for keeping public APIs clean. I am a supporter of treating an exception as soon as possible when most of the calling context is still available.
- What constitutes an exception is to a certain degree relative indeed. But using return codes for it is a really bad solution since there are many situations where the error codes are part of the success return value domain.
- When I talk about handling exceptions as fast as possible I am not talking about the immediate caller as in the method who makes the call. I am speaking about the “framework/layer” who makes the call that causes the exception.
- As a specific example think of a plug-in manager who loads/initializes a bunch of third party plug-ins in a loop. No matter what exception is thrown by a specific initializer I don’t want the loop to stop.
I see the difference in our opinions more philosophical. I think you feel checked exceptions are limiting programmer’s freedom. I see them as enabling better quality and reliability since they take into account human nature.
@mantrid
Thank you. I am going to post in the near future an article about “designing with exceptions”. I will be more detailed there but for now some answers to your questions:
1. I would reuse standard Java exceptions as long as they are generic enough. Some unchecked exceptions fall into this category (obvious example: java.lang.IllegalArgumentException). I would not use exception from specific packages unless there is a real obvious match with what I am doing. I prefer to create my own exception hierarchy for each framework or subsystem I am building.
2. Too much chaining is too much :). As I said exceptions should be treated as soon as possible. This means not too soon (where you don’t know what to do with it) and not too late (where the calling context is lost and the only thing you can do is to log and die). I actually never seen in practice more than 3-4 levels of chaining being necessary. This also comes down to how the application is structured. I think an application should not have more than 4 logical layers of frameworks and utilities. As a consequence I would also aim for a limit of 3 (4 at most) chained exceptions in most situations.
3. If you keep the number of chained exceptions low then handling them doesn’t look too bad. On top of that, if the number of exception types is high then you can imagine a better way of handling then “instanceof”. In such situations it may be justified to create a special framework for registering and calling exception handlers based on type and context.
Interesting article (nice title too ;))
I think checked exceptions are beneficial, but they become cumbersome if they are abused (using a checked exception where an unchecked exception makes more sense).
Another guideline when choosing between checked and unchecked is the idea of “avoidability” or “predictability”.
For example, it makes sense for ArithmeticException to be unchecked. If I divide by zero, I know what is going to happen. I could have checked for it beforehand and avoided the problem with 100% certainty. The fact that an ArithmeticException happens is an indication of a bug that should be fixed, so I’m happy not to have to worry about catching it every time. When it happens (in testing hopefully), I will fix it and it won’t happen again. It’s almost like an assertion that can’t be turned off.
On the other hand, I can’t predict network failure. I can’t be certain before I read from a stream whether it will fail or not. Therefore it makes sense for IOException to be checked. In fact, it is beneficial since it forces me to consider the problem and deal with it.
Its not just the exception hierarchy that has some gotchas. The Interface hierarchy also has it problems. For example java.io.Closeable.
There are a lot of classes that have close methods but cant implement Closeable since they don’t throw the same exception (for ex: the sql package).
A way that was suggested to deal with this was to introduce a Closeable void close () throws Exception interface to java.lang and have the others extend it.
Then you can have a natural resource closure function for all those annoying
try{
something.close();
}catch(Exception e){log}
in the finally part of a containing try block.
Extend it and introduce it as the super type of Closeable too of course. Its funny but there is a tendency to forget that types can be introduced at the top of the tree too.
Good article. In general I would rather have checked exceptions. Runtime exception have always bitten me when I least expect it. I have some thoughts on improvements to the exception system. If you get a chance give it a read and tell me what you think.
http://aberrantcode.blogspot.com/2008/03/try-and-try-again.html
Thanks,
Collin
Nice article. I completely agree Dan. With the current state of powerful IDEs, the extra try/catch or throws should’nt be a problem. But as always, programmer laziness and mistakes will always be.
Hmm! Take a look at how the SpringFramework handles exceptions. This a good blog post, the comments against Java’s checked exceptions are even better. I personally think Java would be a better language if it didn’t have Checked Exceptions.
http://gafter.blogspot.com/2007/05/removing-language-features.html
@Collin:
> Runtime exception have always bitten me when I least expect it.
That is because you don’t expect RuntimeExceptions to occur in your applications. But many times they do, without it being totally catastrophic. For instance if you are using an API that throws RuntimeExceptions rather than Exception.
This is another bad thing about checked exceptions. They lure developers into thinking that only checked exceptions should be handled, but this is in many cases wrong. The result: A half done error handling strategy.
By expecting both checked and unchecked exceptions you do not run into trouble nearly as often. Personally, I throw unchecked exceptions, and handle both types. Only Error’s do I let pass (OutOfMemoryError etc.).
When you say good stuff about checked exception you should NEVER talk about IOException and SQLException. Those two are the reason why so many people dislike checked exceptions. The problem with checked exception is that they are useless.
What can i do if i get IOException? i will pack it in runtime and re-throw, because i dont like to add exception to method signature. Plus i know if i add it once to method signature then everybody that is using is must have it in signature(maybe 1% will handle that exception). most of the time that exception is not something i want to recover from.
In one of my applications i recover from OutOfMemoryError, because i expect it to happen with very big files. So i think OutOfMemoryError should be checked exception. People should think about memory ;> You can recover! So should we make OutOfMemoryException as checked exception and put it in signature of every method? that api would look like jdbc and i believe it would be better.
Raveman: You’re an outlier. Sorry. OutOfMemoryError SHOULD be unchecked.
Why? Because it can happen virtually anywhere at any time and can be totally undetectable or unfeasible to predict in code. It doesn’t even have to be an issue with your code, it could be something happening on the server from another process.
IO and SQL errors are NOT the same since they generally have identifiable areas they occur in and constitute a sort of API component along with return values.