«« Next » « Previous
«« Next » « Previous

Link Details

Announcement

iPhone DZone: Fresh Links On Your iPhone by matt at Sat Jul 05 14:09:51 EDT 2008

Reading DZone on your iPhone just got a little bit easier. Visit http://dzone.com/iphone from your iPhone to try out our beta iPhone support. You can view stories, filter by tags, and login. We'd appreciate your feedback at feedback@dzone.com.

Apathy is the suck. Login and vote now.
Link 79326 thumbnail

By jj83777
via tutorials.jenkov.com
Published: May 06 2008 / 07:28

This text discusses the differences between checked and unchecked exceptions in Java, and argues that unchecked exceptions are often a cleaner alternative. The text finishes with references to Anders Hejlsberg (creator of C#) and James Goslings (creator of Java)'s interviews on the subject at artima.com
  • 10
  • 6
  • 1739
  • 542

Comments

Add your comment
User 131196 avatar

Jakob Jenkov replied ago:

0 votes Vote down Vote up Reply

Dzonelurker... couldn't you put a note up on *why* you voted down the link? Then we could at least have a healthy discussion about it :-)

User 210175 avatar

jtheory replied ago:

0 votes Vote down Vote up Reply

He probably just disagrees with it.
I do as well, though I don't have the time to really write out in detail why. Not bothering to vote down, but not voting up either.

In short, you need to re-evaluate "use checked exceptions for all errors the application can recover from, and unchecked exceptions for the errors the application cannot recover from." Cannot recover from does NOT mean crash -- it means cannot recover from *specifically*.

Unchecked exceptions = cancel the current action, log for debugging purposes, and probably give the user a generic error message. Unchecked exceptions being thrown almost always indicate a bug in your code, and might also trigger auto-reporting, etc..

Checked exceptions = a sometimes unreliable interface has failed -- explain to the user what happened and how they can likely fix it (double-check this URL, or check your internet connection) or try to fix it automatically ("server connection failed... retrying in 5 seconds").

User 131196 avatar

Jakob Jenkov replied ago:

0 votes Vote down Vote up Reply

Hi jtheory, that is probably the most precise and useful distinction I have read to date. Do you mind if I use it in a follow up text on checked/unchecked exceptions?

I am still not sure I'd agree with it 100%. In my experience very few exceptions even from a "sometimes unreliable" can actually be handled/recovered from. The "retrying in 5 seconds" is perhaps the only case I can think of, and yet I may not always want to have the user wait 5, 10, 15 seconds while I retry. I might prefer to abort, log, study the log, and try to fix whatever causes the exception in the first place, be it poor performance or an unstable network connection etc.

I used to be in favor of checked exceptions. But having looked at my, and other peoples, code I just don't find that many places where I can actually do anything else than just log the exception and tell the user that the request failed. In those few cases where I can recover, it usually doesn't matter if it is a RuntimeException or Exception that is thrown. I can still catch it and retry.
,

User 283759 avatar

danielstoner replied ago:

2 votes Vote down Vote up Reply

Hi Jakob,

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!

User 169803 avatar

duckhead replied ago:

0 votes Vote down Vote up Reply

I completely agree with danielstoner. Every time this discussion comes up it seems that those that favor unchecked exceptions have never created truly mission critical (life critical?) software. Too many simplistic approaches rely on 'displaying a useful message to the user'. That's ridiculous. Checked exceptions force the engineer to at least cognitively disregard them. They indicate, "this code may fail in meaningful ways, and I insist you at least consider them." One of the most insidious problems with unchecked exceptions is when they are thrown from a concrete method declared via an interface. Callers of the method would have no expectation of an exception being thrown, and more importantly, different concrete implementations could potentially throw different unchecked exceptions. Doing so violates the Principle of Least Surprise (aka Principle of Least Astonishment).

In 20 years of Ada and Java programming, it has become obvious to me that software properly implemented with checked exceptions leads to robust software more quickly than using unchecked exceptions exclusively. I would even go so far as to say that in typical code written by the average engineer, software using unchecked exceptions would never be as robust as it could be. It's going to take a lot more effort to get the robustness and reliability out of a system developed with only unchecked exceptions. And even then, there would always have the lingering doubt that all possibilities had been accounted for.

User 275836 avatar

albert123 replied ago:

0 votes Vote down Vote up Reply

Hi Duckhead

Just out of curiosity, what do in your code when an SqlException is thrown? or an IOException? I've found it quite difficult to implement a retry strategy for most apps I've been paid to develop. And as in the case of the two aforementioned exceptions (that are thrown for a large number of different reasons), explicitly attending these exceptions require more work than a simple try-catch... i think i prefer an array of junit tests that actually documents the behaviour in error situations than having checked exceptions. I guess this is the debate over the value of static typing versus dynamic typing. While I prefer compile time checks (see e.g. my sql refactoring using eclipse http://sqlorm.sourceforge.net/database_refactoring_made_easy.html) but I think its dangerous to assume that no compile errors mean zero bugs!

Finally, unchecked exceptions makes it easy to implement a closure-like mechanism using the template design pattern.

Keep the debate going ;-)

-kasper

User 169803 avatar

duckhead replied ago:

0 votes Vote down Vote up Reply

So in other words, would SQLException and IOException be better off as descending from RuntimeException? If they were, how would you implement that? A try/catch block that listed every conceivable subclass of RuntimeException? How do you know you're covering every possible exception thrown? The compiler isn't going to help you. Or do you have a master try/catch block that catches RuntimeException at the top of the your call stack? If so, it would be impossible in most cases to try to recover from that because you'd be so far removed from the point at which something meaningful could take place. Help me understand what that would look like.

To your specific question, on many occasions I have implemented retry logic with the subclasses of IOException, especially in socket level code, with great success. The resulting systems were extremely reliable and fault tolerant. Had they been RuntimeExceptions, it would have taken a lot more work (digging though JavaDoc, trial and error, testing, etc.) to find the corner cases. The fact that they were checked exceptions forced me to stop and consider the appropriate action to take at the time the code was created. To me, that's invaluable in terms of both productivity and reliability.

I don't see how anything in my previous post could imply that the lack of compilation errors equates to bug-free code. Although I do favor eliminating entire classes of defects by using the type system of the language, enforced by the compiler, whenever possible. An example of this is using enums instead of codified integers.

I think it's dangerous to assume that an array of passing junit tests (and 100% code coverage for that matter) means zero bugs!

User 254602 avatar

nwbrown replied ago:

0 votes Vote down Vote up Reply

"So in other words, would SQLException and IOException be better off as descending from RuntimeException? If they were, how would you implement that? A try/catch block that listed every conceivable subclass of RuntimeException? How do you know you're covering every possible exception thrown? The compiler isn't going to help you. Or do you have a master try/catch block that catches RuntimeException at the top of the your call stack? If so, it would be impossible in most cases to try to recover from that because you'd be so far removed from the point at which something meaningful could take place. Help me understand what that would look like. "
Just because an exception is unchecked doesn't mean you can't declare that it is thrown. Thats the fallacy I often see being used by people who advocate for checked exceptions. It is true that checked exceptions have to be declared, but that statement's inverse is plainly false.

"To your specific question, on many occasions I have implemented retry logic with the subclasses of IOException, especially in socket level code, with great success. The resulting systems were extremely reliable and fault tolerant. Had they been RuntimeExceptions, it would have taken a lot more work (digging though JavaDoc, trial and error, testing, etc.) to find the corner cases. The fact that they were checked exceptions forced me to stop and consider the appropriate action to take at the time the code was created. To me, that's invaluable in terms of both productivity and reliability. "
I hate to break it to you, but you almost certainly did not find all the corner cases. If you application were like any typical application, you found a small subset of the corner cases while looking at the declared exceptions. I'm positive there were plenty of others which you missed if that were your only way of finding them. And in the process, you likely had to evaluate many corner cases which you could know could not possibly occur, or for which you had no way at all to recover from.

Thats the problem with using checked exceptions, the method writer is making the decision of whether or not the method user will write handling code, without knowing how their method is going to be used. If they are defined as unchecked exceptions which are declared in the method, then the method user can determine how they will be handled.

User 131196 avatar

Jakob Jenkov replied ago:

0 votes Vote down Vote up Reply

I agree with albert123

I develop mission critical systems for banks, and shipping companies. How about if the largest container shipping company in the world had their systems crash due to an unhandled exception? Or the international bank associations systems offered to banks, crash because they use unchecked exceptions only? Or all the projects based on Spring? Yet the projects chose *unchecked* exceptions, and the system... *run*.

It's like crying "wolf"... The wolf may come, theoretically, I just haven't seen the wolf yet in reality. I am slowly changing all my apps and recommendations to unchecked exceptions... I still haven't experienced a more unstable system using unchecked exceptions than with checked exceptions. In fact, using unchecked exceptions forces me to think about possible exceptions *every time* I call some code I didn't write myself - both checked and unchecked! There is no big difference, except the code is more readable when using unchecked exceptions.


I feel tempted to put up a competition... to put up a prize for every time someone can show me an exception they could actually handle sensible in the situation, rather than just abort the current request/action etc.

User 283759 avatar

danielstoner replied ago:

0 votes Vote down Vote up Reply

At http://www.littletutorials.com I have a series of posts where I explain my position on the subject in greater detail. I fully agree with Duckhead. Programs should try to recover from errors and not roll over and die. Of course you can do the same thing with unchecked exceptions but it is harder because you have no help from the compiler. And it is not only about YOU. It is also about the junior programmer assigned a piece of code, it is about the maintenance developer who fixes bugs and can introduce new ones and so on. With an SQLException, checked or unchecked one should do everything possible to recover. You have to analyze the exception in the context it occured (not 10 levels down the stack) and decide what has to be done. You might have a corrupted schema, you might have an unavailable server, but you can still do something in most cases, like connecting to the standby database server. The server should never crash or get into a state where it has to be reinitialized. But there is no point in rewriting my posts here....

Here are the links if you are interested:

* 1. Thoughts on Java exceptions - http://littletutorials.com/2008/04/27/exceptional-java-thoughts-on-java-exceptions
* 2. Some exceptions are more equal than others - http://littletutorials.com/2008/05/01/exceptional-java-some-exceptions-are-more-equal-than-others
* 3. Less than perfect exceptions hierarchy - http://littletutorials.com/2008/05/05/exceptional-java-less-than-perfect-exceptions-hierarchy
* 4. Checked exceptions are priceless… For everything else there is the RuntimeException - http://littletutorials.com/2008/05/06/exceptional-java-checked-exceptions-are-priceless-for-everything-else-there-is-the-the-runtimeexception

User 283759 avatar

danielstoner replied ago:

0 votes Vote down Vote up Reply

Hi Jakob,

Sorry but we disagree on the wrong topic. The point is not that one cannot do the same thing with checked or unchecked exceptions. You can get the exact same results. The point in my opinion is that checked exceptions help pressured programmers avoid costly mistakes.

User 254602 avatar

nwbrown replied ago:

0 votes Vote down Vote up Reply

No, thats not true at all (at least not in the real world where developers are all hurrying to get their code written in time and on budget). All checked exceptions do is pressure developers to write canned try catch blocks that either log an error or do nothing at all.

User 131196 avatar

Jakob Jenkov replied ago:

0 votes Vote down Vote up Reply

I used to believe in that too, Daniel, that checked exceptions help developers. I just haven't seen much evidence to support that belief in reality though. Without evidence, it's just a belief, and beliefs are useless in a scientific world. The non-believers, why don't you try out doing an app with unchecked exceptions, and see what happens?

First of all, who is the junior programmer who doesn't know how to handle exceptions? I have never met him anywhere. I have seen lots of bad code yes, but from *experienced* developers working on a messy system, under pressure.

Second, to such a junior programmer, don't you think that the choice of either

a) handling the error locally
b) wrap it in an app specific exception and rethrow it
c) let the original exception pass through to higher layers

is just as hard a choice to make, whenever the compiler forces you to deal with a checked exception?

User 131196 avatar

Jakob Jenkov replied ago:

0 votes Vote down Vote up Reply

... and one more comment @danielstoner

What you *can* do in the face of a checked exception is one thing, but why don't you go back into your code and see *what you actually do* ? I'd be curious about that.

In the code I have seen, the system usually just aborts the current transaction. I have never seen a system connect to a standby database. Database clustering is usually invisible to the application (or am I wrong?).

Many of the proposed local error handling actions spawn new problems of their own.

So I connect to a standby database because the original database is down. Who synchronizes the two databases afterwards?

So I retry connecting to the database, because it is down, but for how long, and how many times? And what do I do if the database doesn't come back up within that time? And again, *if* the database is down, will it actually come back up within the allowed waiting time? Won't it take more than the 30 secs waiting time allowed anyways?

So the file is gone, but retrying to read it won't make it come back, will it?

So a web service is down, but again, how long should you wait for it to come back up, before cancelling the transaction?

Many of these local error handling schemes raise so many new questions that most of the code I have seen just plays it safe, and aborts the transaction right away.

And this is NOT the same as saying the code does not do try-finally to close connections etc. When using unchecked exceptions there are lots of try-finally in the code, just as many as with checked exceptions.

Add your comment


Html tags not supported. Reply is editable for 5 minutes. Use [code lang="java|ruby|sql|css|xml"][/code] to post code snippets.