4 ms·
An Uneducated View of Checked vs. Unchecked Exceptions
- russell 17y agoBruce Eclkel's pretty much state the anti-checked-exception camp: http://www.mindview.net/Etc/Discussions/CheckedExceptions http://www.mindview.net/Etc/Discussions/CheckedExceptions There are very good comments from both points of view. The blog was written several years ago, so his solution is somewhat dated. I think checked exceptions are a bad idea for a couple of reasons. First is their most acclaimed benefit: they force you to deal with the exception immediately, even if you have no solution for it. You have to decide whether to catch the exception or add a throws clause, which changes the method signature and breaks it for any users of your method. The the default decision for many programmers is to log the exception and swallow it, intending to come back later. I have had to dig through applications to find sql exceptions that were caught but not dealt with. The second big problem I find is the poor design of exception classes. It is not uncommon to find a class that throws a half-dozen exceptions. Every time you call a new method you have a new exception to deal with. Either it should have a single exception with different error codes for the different cases, or the exceptions should be subclassed from a master exception.
- lucifer 17y ago"I think checked exceptions are a bad idea for a couple of reasons. First is their most acclaimed benefit: they force you to deal with the exception immediately, even if you have no solution for it." The use of the word "immediately" informs your misunderstanding of the purpose of a checked exception. Checked exceptions are enforced at compile time (thus "checked" exception). There is no such thing as 'temporal immediacy' at compile time (unlike runtime exceptions). There is potential for spatial immediacy (if we consider the static call stack), but that is not what the compiler cares about. (In other words, you can catch exception Foo at the call site and delegate handling up the call stack by throwing a Bar (cause: Foo)). A compiler enforced handling of an exception declaration insures that the program handles the exception at some level in the call stack, as apparent to the compiler. This whole (endless) discussion regarding checked/unchecked very much mirrors the static-typing/dynamic-typing discussion. You can either consider the merits pragmatically, or, you can adopt a dogmatic (religious) point of view that embraces one paradigm and dismisses the other.
- barrkel 17y agoProgramming languages shape the way programmers solve problems. To use your terms, when a compiler forces one to deal with a problem with spatial immediacy (i.e. checked exceptions), and the language uses spatial colocation to represent temporal colocation to a greater or lesser degree (as most imperative languages do), then the programmer is being encouraged, quite strongly, to solve the problem in similar space and by consequence in similar time.
- lucifer 17y agoYou make a very persuasive point, but I have reservation regarding the words "encourage" and "solve". I would think the fact of the possibility of mapping exceptions (according to some abstraction order mirroring the layering of the overall system) calls for "acknowledge" instead of "solve". And compilers can help with robustness of programs, but their influence on the robustness of programmers is not immediately evident. So perhaps "suggests" instead of "encourage" for a subset of programmers?
- barrkel 17y agoThe failure modes of software written in C versus memory safe languages, with particular attention to security and buffer overflows, persuades me very strongly that languages (and their implementations, i.e. compilers) do indeed influence the robustness of programmers. What is a programmer other than the programs he writes?
- russell 17y agoBy "immediately", I meant as you write the code. Type the code, hit return, and you have an error. "Immediately" you have to decide add a try or change the method signature. I think this causes premature exception handling, just because the programmer wants to get moving along with the code. Checked/unchecked seems to mirror static/dynamic typing, but it doesnt. It's orthogonal. Exception handling is an application specific implementation strategy, but checked exceptions force a "religion" on you.
- scotty79 17y ago
- dlsspy 17y agoI wrote a blog post a long time ago into a response of a big list someone made of exception handling anti-patterns which (in my opinion) are made possible by checked exceptions. http://www.rockstarprogrammer.org/post/2007/jun/09/java-exception-antipatterns/ http://www.rockstarprogrammer.org/post/2007/jun/09/java-exce...
- jacquesm 17y agoExceptions are now a 'way of life' for many different programming environments, the simplistic view is that they allow your program to 'catch' any unforeseen issues at a lower level in a graceful way. The truth is that the 'handling' is often much less robust than it ought to be, which in turn will lead to the hiding of problems at lower layers. A simple example would be an I/O error when reading a file, if you 'handle the exception' then you have done absolutely nothing to take care of the underlying problem. Personally I'm a huge fan of spending the extra time required when writing lower level code to make sure that all cases are handled properly, instead of throwing an exception at the slightest sign of trouble. A pet example of this is the UTF-8 and unicode conversion library, when presented with an 'undefined' character lots of libraries will cause a whole series of exceptions to be triggered because of a single character issue in some data to be imported. If such a library were defined 'properly' then you'd tell it what to do with 'bad' input, toss it, replace it with ##undefined character## (or any other string you come up with) or, in case you want it, throw an exception. The defaults should be sensible and should maximize productivity. That way the user of such a library knows the library will handle the job with a minimum of fuss. I see exceptions mostly being used as a way to be absolved from further responsibility from an issue, and that's really not the way they should be used. Run time errors are uniformly bad, exceptions really are a form of runtime error and should be avoided as much as possible. Especially in lower level code.
- barrkel 17y agoI strongly disagree that exceptions are about catching unforeseen issues at a lower level. Exceptions should almost never be caught. A well-written program will have only a handful of exception handlers that don't repropagate the exception; ideally only one, at the highest level of the event loop or request handler. As to your string decoder example, the sensible default should be to throw an exception, with an easily available out to replacements etc. as you suggest. String conversion across multiple code pages is an interesting example precisely because data loss is so easy, and if the problems aren't raised early in the data flow, it can be hard to figure out where it went wrong. The "default" manifests itself in Windows programs as '?' - rather annoying to debug when the first time you see it is on the UI, while other concrete are plentiful on the web. A very common example is balanced "smart" quotes, which frequently end up encoded in either the web page or the RSS feed in a different encoding than that described in the HTTP header, or in the meta tag, or according to the relevant standards, etc. Yes, runtime errors should be avoided, but not by the lower-level code; rather, the lower-level code should throw exceptions when error conditions occur, but have ways and means for programs that care about the exceptional conditions to not throw exceptions. This isn't always possible, though. Consider TFA's example of file not found: > The caller can't recover from a file not found error The caller can test to see if a file exists before trying to read it, but non-transactional interactions like this with the file system are subject to races; the file might exist one microsecond and be gone the next. But it is also obviously true that the caller can recover from a file not found error. Concrete example: consider a thumbnail generating service, which checks to see if a cached thumbnail file exists before doing the expensive work of creating it if necessary. Here, a file not found exception (perhaps caused by concurrent cleanup of cache, for random operational reasons) is indeed not fatal.
- jerf 17y agoI make the following observation: Everybody I've seen arguing in favor of checked exceptions in the past couple of years have argued about their theoretical benefits. Everybody who is arguing against them have argued about how they have not worked out in real life. This pattern seems to recur a lot in programming debates, where people don't seem to realize that it doesn't matter how wonderful your theory is if when you try it out, it's wrong. That's where checked exceptions are. The time for theorizing about their effects on programs is long, long past. Who cares whether they theoretically force programmers to write better code? We now know that in reality, it actually results in worse programs the majority of the time. When theory and reality disagree, theory is wrong. Why anybody still talks about their theoretical design goals is beyond me. As near as I can tell, the debate is over if you ignore the people who haven't let their theories catch up to reality. If someone's got a success story posted about how checked exceptions saved their program's bum, I'm interested in the link, but I haven't seen one. (I say it that way because when you have something enough people will read you can always find someone to pop up and claim that "X is good", but I'm specifically asking for arguments that already existed prior to this post, to avoid selection bias effects.)
- barrkel 17y agoFirst up: I'm not a fan of checked exceptions. But on the other hand, I must point out: checked exceptions certainly force you to address the issue of the exception being thrown, and as a result, the failure mode that they prevent can't occur, so the evidence you're seeking is more or less impossible. On the other hand, checked exceptions have their own failure modes, down to human behaviour: rather than having to rewrite every method declaration on the call graph to throw the appropriate list of exceptions, some bad apples just catch exceptions and do nothing with them. This shuts up the compiler, but harms product quality. IMO, the theory behind checked exceptions is actually fundamentally mistaken. Exceptions aren't much good if you're constantly trying to catch them. Exceptions work best if you write your code in a transactional style, more or less assuming that an exception can occur at any moment, on any operation. This can be tricky: it can force you to make or keep copies of structures when doing large structural modifications; but this difficulty is not strictly due to exceptions, as failures modes need to be dealt with in any case.
- adatta02 17y agotry{ somecode(); }catch(Exception ex){ // eh this will NEVER happen }
- cema 17y agoExactly! :-)
- smanek 17y agoAs a professional Java programmer, with some experience in various strongly typed languages (MLs, Haskell), I really liked the idea of Checked Exceptions when I first heard about them (and even when I used them in small projects in school). In principle, it seems like a way to allow for stronger static analysis and allows the compiler to make stronger safety guarantees. It also forces programmers to deal with oddball cases - instead of just ignoring them like we are prone to do with magic return values (a la C) or unchecked exceptions. The problem is it never works. There are two common strategies that I've encountered to deal with 90+% of checked exceptions: -Most code just bubbles the exceptions up the top layer (i.e., the UI), which clutters up every method signature along the way. The UI then has a big handler that catches all exceptions, and just logs an error and shuts down the program. Even on the off chance that the top-level could do something more productive, the problem is that the stack has been unwound too far and it's too late to fix whatever the problem is. -The other common approach is to wrap every checked exception inside a custom unchecked exception that is just thrown. This is my preferred solution (at least it doesn't clutter up every method signature), but I have to explicitly convert every checked exception into an unchecked one - which is just a bit of a hassle. I give Sun some props for trying out on a limb with a really cool sounding idea. But I think most people have realized it doesn't work very well in practice ...
- scotty79 17y agoMaybe it would be more useful to declare what types of exceptions method handles. Declaring what types of exceptions methods (throws|receives and not handles) should be optional. The way it is now is too much work and too little gain in typical setups.
- russell 17y agoIIRC that's what C++ does and I recently read that it's mostly ignored. Of course a compiler or IDE could detect what is caught and generate the javadoc equivalent. That would be useful.
- jsankey 17y agoIMO almost all of the problems people have in practice with checked exceptions are from poor API design rather than an issue with checked exceptions themselves. The core Java APIs use checked exceptions for too many conditions which are not recoverable - causing a whole bunch of maintenance pain for no benefit. This is understandable considering that Java was the first mainstream language to really exercise the concept. If used judiciously, I think checked exceptions do have benefits. There are classes of errors that are exceptional but also conceivably recoverable. The fact that they are exceptional means it is important to draw attention to them (they may otherwise be overlooked). The fact that they are recoverable justifies requiring calling code to make a choice - handle or propagate the error. Even in these cases, the code can get messy, but I see that as a fact of life: writing robust code isn't easy.