Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Java's checked exceptions have gotten some bad press over the years. A telling sign is that it's literally the only language in the world that has them (not even other JVM languages like Groovy and Scala). Prominent Java libraries like Spring and Hibernate also don't use them.

I personally have found one use for them (in business logic between layers), but otherwise I'm pretty anti-checked exceptions.

Are there any other uses that I don't realize?

share|improve this question

closed as too broad by gnat, MichaelT, GlenH7, jwenting, Bart van Ingen Schenau Apr 28 at 12:45

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

    
All Java core libraries use checked exceptions quite extensively. –  Joonas Pulakka Nov 16 '10 at 7:40
3  
@Joonas I know, and it's a pain! –  Brad Cupit Nov 16 '10 at 12:59

8 Answers 8

up vote 20 down vote accepted

First of all, like any other programming paradigm you need to do it right for it to work well.

For me the advantage of checked exceptions is that the authors of the Java runtime library ALREADY have decided for me what common problems I might reasonably be expected to be able to handle at the calling point (as opposed to a top-level catch-print-die block) and consider as early as possible how to handle these problems.

I like checked exceptions because they make my code more robust by forcing me to think about error recovery as early as possible.

To be more precise, to me this makes my code more robust as it forces me to consider strange corner cases very early in the process as opposed to saying "Oops, my code does not handle if the file doesn't exist yet" based on an error in production, which you then have to rework your code to handle. Adding error handling to existing code can be a non-trivial task - and hence expensive - when reaching maintenance as opposed to just doing it right from the start.

It might be that the missing file is a fatal thing and should cause the program to crash in flames, but then you make that decision with

} catch (FileNotFoundException e) {
  throw new RuntimeException("Important file not present", e);
}

This also shows a very important side effect. If you wrap an exception, you can add an explanation which goes in the stack-trace! This is so extremely powerful because you can add information about e.g. the name of the file that was missing, or the parameters passed to this method or other diagnostic information, and that information is present right in the stack trace which frequently is the single thing you get when a program has crashed.

People may say "we can just run this in the debugger to reproduce", but I have found that very frequently production errors cannot be reproduced later, and we cannot run debuggers in production except for very nasty cases where essentially your job is at stake.

The more information in your stack trace, the better. Checked exceptions help me get that information in there, and early.


EDIT: This goes for library designers as well. One library I use on a daily basis contains many, many checked exceptions which could have been designed much better making it less tedious to use.

share|improve this answer
    
+1. Spring's designers did a good job of translating a lot of the Hibernate exceptions into unchecked exceptions. –  unsquared Nov 18 '10 at 20:31
    
FYI: Frank Sommers mentioned in this thread that fault-tolerant software often rely on the very same mechanism. Perhaps you can subdivide your answer into the recoverable case and the fatal case. –  rwong May 14 '11 at 10:25
    
@rwong, could you please explain in more detail what you have in mind`? –  user1249 May 16 '11 at 9:37

They're really good for annoying programmers and encouraging exception swallowing. Half the point of exceptions is so that you have a sane default way of handling errors and don't have to think about explicitly propagating error conditions you can't handle. (The sane default being that if you never handle the error anywhere in your code, you've effectively asserted that it can't happen, and are left with a sane exit and a stack trace if you're wrong.) Checked exceptions defeat this. They feel a lot like having to explicitly propagate errors in C.

share|improve this answer
3  
Easy fix: throws FileNotFoundException. Hard fix: catch (FileNotFoundException e) { throw RuntimeException(e); } –  Thomas Eding Oct 9 '12 at 18:39

I think it is fair to say that checked exceptions were a bit of a failed experiment. Where they went wrong is that they broke layering:

  • Module A might be built on top of Module B, where
  • Module B might be built on top of Module C.
  • Module C might know how to identify an error, and
  • Module A might know how to handle the error.

The nice separation of concerned is broken, because now knowledge of errors that could have been limited to A and C now have to be scattered over B.

There is a nice discussion of checked exceptions on Wikipedia.

And Bruce Eckel has a nice article on it as well. Here's a quote:

[T]he more random rules you pile onto the programmer, rules that have nothing to do with solving the problem at hand, the slower the programmer can produce. And this does not appear to be a linear factor, but an exponential one

I believe for the case of C++, if all methods have the throws specification clause, then you can have some nice optimizations. I don't believe Java could have those advantages anyway, though, because RuntimeExceptions aren't checked. A modern JIT should be able to optimize the code just fine anyway.

One nice feature of AspectJ is exception softening: You can turn checked exceptions into unchecked exceptions, specifically to enhance layering.

Perhaps it's ironic that Java went through all of this trouble, when it could have checked for null instead, which might have been much more valuable.

share|improve this answer
    
haha, never thought about that checking for null thing as a decision they didn't make... But I finally understood that it's NOT an innate problem after working in Objective-C, which allows nulls to have methods called. –  Yar Nov 16 '10 at 4:23
3  
null-checking is a much greater pain - you ALWAYS have to check - plus it does not tell the reason why, which a well-named exception does. –  user1249 Nov 16 '10 at 4:41

You've got two good answers which explain what checked exceptions have become in practice. (+1 to both.) But it would also be worthwhile to examine what they were intended for in theory, because the intention is actually worthwhile.

Checked exceptions are actually intended to make the language more type safe. Consider a simple method like integer multiplication. You might think that the result type of this method would be an integer, but, strictly speaking, the result is either an integer or an overflow exception. Considering the integer result by itself as the return type of the method does not express the full range of the function.

Seen in this light, it's not strictly true to say that checked exceptions have not found their way into other languages. They have just not taken the form that Java used. In Haskell applications, it is common to use algebraic data types to distinguish between successful and unsuccessful completion of the function. Although this is not an exception, per se, the intention is very much the same as a checked exception; it is an API designed to force the API consumer to handle both the successful in the unsuccessful case, e.g.:

data Foo a =
     Success a
   | DidNotWorkBecauseOfA
   | DidNotWorkBecauseOfB

This tells the programmer that the function has two additional possible results besides success.

share|improve this answer

Checked exceptions are also in ADA.

(Warning, this post contains strongly held beliefs that you might find confronting.)

Programmers don't like them and complain, or write exception swallowing code.

Checked exceptions exist because things can not only fail to work, you can do a failure mode/effects analysis and determine this in advance.

File reads can fail. RPC calls can fail. Network IO can fail. Data can be mis-formatted when parsed.

The "happy path" for code is easy.

I knew a guy at University who could write great "happy path" code. None of the edge cases ever worked. These days he does Python for an open source company. Nuff said.

If you don't want to handle checked exceptions, what you're really saying is

While I'm writing this code, I don't want to consider obvious failure modes.

The User will just have to like the program crashing or doing weird things.

But that's okay with me because 

I'm so much more important than the people who will have to use the software

in the real, messy, error-prone world.

After all, I write the code once, you use it all day long.

So checked exceptions are not going to be liked by programmers, because it means more work.

Of course, other people might have wanted that work done.

They might have wanted the right answer even if the file server failed/ USB stick dies.

It's a strange belief in the programming community that you should be using a programming language that makes your life easier, that you enjoy, when your job is to write software. You job is solving someones problem, not letting you engage in programmatic Jazz improvisation.

If you're an amateur programmer (not programming for money), feel free to program in C# or some other language with no checked exceptions. Heck, cut out the middle man and program in Logo. You can draw pretty patterns on the floor with the turtle.

share|improve this answer
6  
Nice rant you got there. –  Anna Lear Nov 16 '10 at 3:22
2  
+1 "None of the edge cases ever worked. These days he does Python for an open source company. Nuff said." Classic –  NimChimpsky Dec 15 '10 at 17:02
1  
@palto: Java forces you to consider the non-easy path. That's the big difference. For C#, you might say, "The exception is documented" and wash your hands of it. But programmers are error prone. They forget things. When I write code, I want to be 100% reminded of any cracks a compiler can inform me. –  Thomas Eding Oct 9 '12 at 18:56
2  
@ThomasEding Java forces me to handle the exception where the method is called. It is very rare that I actually want to do something about it in the calling code and usually I want to bubble up the exception to the error handling layer of my application. I then have to remedy it with either wrapping up the exception in a Runtime exception or I have to create my own exception. Lazy programmers have a third option: just ignore it because I don't care. That way no one knows the error happened and the software has really odd bugs. That 3rd one doesn't happen with unchecked exceptions. –  palto Oct 10 '12 at 6:35
3  
@ThomasEding Doing that will change the interface of everything above which reveals implementation details needlessly to every layer of the application. You can only do that if the exception is something you want to recover from and it makes sense in the interface. I don't want to add a IOException to my getPeople-method because some configuration file might be missing. It just doens't make sense. –  palto Oct 11 '12 at 18:32

Checked exceptions should have encouraged people to handle errors close to there source. The further away from the source, the more functions have terminated in the middle of running, and the more likely that the system has entered an inconsistent state. Additionally, it is more likely that you catch the wrong exception by accident.

Sadly, people have tended to either ignore exceptions or add ever increasing throw specifications. Both of these miss the point of what checked exceptions are suppose to encourage. They are like transforming procedural code to use many Getter and Setter functions supposedly making it OO.

Essentially, checked exceptions are attempting to prove a certain degree of correctness in your code. Its pretty much the same idea as static typing, in that it attempts to prove that certain things are correct before the code even runs. The problem is that all of that extra proof takes effort and is the effort worthwhile?

share|improve this answer
2  
"Ignoring exceptions" is often correct -- many times the best response to an exception is to let the app crash. For a theoretical basis for this point of view, read Bertrand Meyer's Object Oriented Software Construction. He shows that if exceptions are used properly (for contract violations) that there are essentially two correct responses: (1) let the app crash or (2) fix the problem which caused the exception and restart the process. Read Meyer for details; it's hard to summarize in a comment. –  Craig Stuntz Nov 16 '10 at 13:40
1  
@Craig Stuntz, by ignoring exceptions I meant swallowing them. –  Winston Ewert Nov 16 '10 at 14:17
    
Ah, that is different. I agree you should not swallow them. –  Craig Stuntz Nov 16 '10 at 15:30
    
"Ignoring exceptions is often correct -- many times the best response to an exception is to let the app crash.": It really depends on the application. If you have an uncaught exception in a web application the worst that can happen is that your customer will report seeing an error message on a web page, and you can deploy a bug fix within a few minutes. If you have an exception while an aeroplane is landing, you'd better handle it and try to recover. –  Giorgio Apr 27 at 15:41
    
@Giorgio, very true. Although I wonder if in the case of aeroplane or similar if the best way to recover is to reboot the system. –  Winston Ewert Apr 27 at 23:01

IMO, checked exceptions are a flawed implementation of what might have been a pretty decent idea (under completely different circumstances -- but really isn't even a good idea under the current circumstance).

The good idea is that it would be nice to have the compiler verify that all exceptions that a program has a potential to throw will be caught. The flawed implementation is that to do that, Java forces you to deal with the exception directly in whatever class invokes anything that's declared to throw a checked exception. One of the most basic ideas (and advantages) of exception handling is that in case of an error, it allows intermediate layers of code that have nothing to do with a particular error, to completely ignore its very existence. Checked exceptions (as implemented in Java) don't allow that, thus destroying a major (the primary?) advantage of exception handling to start with.

In theory, they could have made checked exceptions useful by enforcing them only on a program-wide basis -- i.e., while "building" the program, build a tree of all the control paths in the program. Various nodes in the tree would be annotated with 1) exceptions they can generate, and 2) exceptions they can catch. To assure the program was correct, you'd then walk the tree, verifying that every exception that was thrown at any level in the tree was caught at some higher level in the tree.

The reason they didn't do that (I'd guess, anyway) is that doing so would be excruciatingly difficult -- in fact, I doubt anybody's written a build system that can do that for anything but extremely simple (bordering on "toy") languages/systems. For Java, things like dynamic class loading render it even more difficult than in many other cases. Worse, (unlike something like C) Java isn't (at least normally) statically compiled/linked to an executable. That means nothing in the system really has the global awareness to even try to do this kind of enforcement until the end user actually starts to load the program to run it.

Doing enforcement at that point is impractical for a couple of reasons. First of all, even at best it would extend startup times, which are already one of the single biggest, most common complaints about Java. Second, to do much good, you really need to detect the problem early enough for a programmer to fix it. When the user is loading the program, it's too late to do much good -- your only choices at that point are to ignore the problem, or refuse to load/run the program at all, on the off chance that there might be an exception that wasn't caught.

As they are, checked exceptions are worse than useless, but alternative designs for checked exceptions are even worse. While the basic idea for checked exceptions seems like a good one, it's really not very good, and happens to be a particularly poor fit for Java. For something like C++, that's normally compiled/linked into a complete executable with nothing much like reflection/dynamic class loading, you'd stand a little more chance (though, quite frankly, even then enforcing them correctly without the same kind of mess they currently cause in Java would still probably be beyond the current state of the art).

share|improve this answer
    
Your very first initial statement about having to handle the exception directly is already false; you can simply add a throws statement, and that throws statement may be of a parent type. Furthermore, if you really don't think you have to handle it you can simply convert it to a RuntimeException instead. IDE's commonly help you with both tasks. –  Maarten Bodewes - owlstead Apr 26 at 10:32
1  
@owlstead: Thanks--I probably should have been more careful with the wording there. The point wasn't so much that you actually had to catch the exception as it was that every intermediate level of code needs to be aware of every exception that might flow through it. As for the rest: having a tool that makes it quick and easy to make a mess of your code doesn't change the fact that it's making a mess of the code. –  Jerry Coffin Apr 26 at 17:30
    
Checked exceptions were intended for contingencies -- predictable & recoverable outcomes other than success, as distinct from failures -- unpredictable low-level/ or system problems. FileNotFound or error opening a JDBC connection were both correctly considered contingencies. Unfortunately, Java library designers made a total mistake & assigned all other IO and SQL exceptions to the 'checked' class also; despite these being almost completely unrecoverable. literatejava.com/exceptions/… –  Thomas W Jun 2 at 9:47
    
@owlstead: Checked exceptions should only bubble through intermediate layers of the call stack if they are thrown in cases that the intermediate calling code expects. IMHO, checked exceptions would have been a good thing if callers had to either catch them or indicate whether or not they were expected; unexpected exceptions should be automatically wrapped in an UnexpectedException type derived from RuntimeException. Note that "throws" and "doesn't expect" are not contradictory; if foo throws BozException and calls bar, that doesn't mean it expects bar to throw BozException. –  supercat Jul 9 at 20:59

I love exceptions.

I am, however, constantly bemused by their miss-use.

  1. Don't use them for flow-handling. You don't want code that tries to do something and uses an exception as a trigger to do something else instead because Exceptions are objects that need to be created and use memory etc. etc. just because you couldn't be bothered to write some kind of if() check before you made your call. That's just lazy and gives the glorious Exception a bad name.

  2. Don't swallow them. Ever. Under any circumstances. As an absolute minimum you stick something in your log file to indicate that an Exception happened. Trying to track your way through code that swallows exceptions is a nightmare. Again, curse you exception-swallowers for bringing the mighty Exception into disrepute!

  3. Do treat Exceptions with your OO hat on. Create your own Exception objects with meaningful hierarchies. Layer your business logic and your exceptions hand in hand. I used to find that if I started on a new area of a system I'd find the need to sub-class Exception within half an hour of coding so these days I start by writing the Exception classes.

  4. If you're writing 'frameworky' bits of code, make sure all your initial interfaces are written to throw your own new Exceptions where appropriate... and make sure your coders have some sample code around the place of what to do when their code throws an IOException but the interface they're writing to wants to throw a 'ReportingApplicationException'.

Once you've groked how to make Exceptions work for you you'll never look back.

share|improve this answer
2  
+1 for good instructions. Also, where appropriate, use initCause or initialize the exception with the exception that caused it. Example: You have an I/O utility that you only need an exception if the write fails. However, there are multiple reasons that a write could fail (couldn't get access, write error, etc.) Throw your custom exception with the cause one so that the original problem is not swallowed. –  Michael K Nov 18 '10 at 16:54
2  
I don't want to be rude but what does this have to do with CHECKED exceptions? :) –  palto Jun 12 '12 at 13:54
    
Could be rewritten to write your own hierarchy of checked exceptions. –  Maarten Bodewes - owlstead Apr 26 at 10:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.