Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Exceptions  RSS feed

 
Raj Kumar Bindal
Ranch Hand
Posts: 418
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a big doubt that why does some checked exceptions like IOException,ServletException exist.I mean that developer is unnecessarily getting forced either to hadle these through try/catch or throw these using throws clause.Is there any special purpose for which these exceptions has been made checked.
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 37242
519
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What you said - so the developer is forced to think about it. if an IO Exception occurs, what should happen? Sometimes there is a logical default. Other times, we just want to add a throws clause to let the exception go through and call it a fatal error.
 
Raj Kumar Bindal
Ranch Hand
Posts: 418
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your reply seems fine but still i think that if developer is developing well,why should he be forced to use throws clause.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Raj Kumar Bindal:
Your reply seems fine but still i think that if developer is developing well,why should he be forced to use throws clause.


I can't think of a time when you're forced to use "throws" on a method, other than the obvious time when you choose to throw a checked exception type yourself. Otherwise, you always have the alternative of catching the exception and dealing with it locally. In other words, you always have these two choices:



Now, if somebody calls the second version of this method, they have to check whether the return value is null; but they can forget. If they call the first one, they know that if the method returns, it succeeded. So the first one uses less code, requires less code every time it is called, and is safer because the client can't forget to handle the case where the file doesn't exist. The second one... well, the second one doesn't say "throws IOException". Seems like a bad trade to me personally.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The second choice is pretty appalling, really, as it loses all stack trace info and makes it likely that the error will be overlooked. But there are other options:

Now there's no need to check for a null return value, and if the method returns at all, then it was successful. Calling code is not forced to handle the thrown exception, but it has the option. Actually this would work even better with a custom class extending RuntimeException, so that calling code could catch this specific exception without also catching things like NullPointerException. Note also that the code above didn't merely throw the new exception, but it wrapped the original exception and added diagnostic information (the name of the files, which is not necessarily present in the IOException). This can be useful for debugging.

This strategy of catching checked exceptions and rethrowing them as unchecked is not generally recommended by Sun, but it has become more popular in recent years in code from other sources. Spring, JDO, TopLink, Hibernate - all of these now make extensive use of unchecked exceptions in places Sun would use checked exceptions.

There's been a fair amount of discussion of the merits of checked exceptions vs. unchecked. Some good reading can be found at:

http://www.ibm.com/developerworks/java/library/j-jtp05254.html
http://gafter.blogspot.com/2007/05/removing-language-features.html
http://www.briangoetz.com/blog/?p=43
[ December 09, 2007: Message edited by: Jim Yingst ]
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
that seems to be fine Jim. But then what exactly it adds to leaving it as such and returning null as EFH has done?

In both the cases, the user is left free to check for the exceptions as they are handled inside the called method. You can even print out the same diagnostic information in the catch block before returning null.

What extra advantage it adds?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[RKB]: In both the cases, the user is left free to check for the exceptions as they are handled inside the called method.

But what happens if the user takes the simplest route, and does not do anything to check for an exception? If you return null, the user will miss the problem entirely. Or perhaps they will get a NullPointerException later, but it will take extra work to figure out what really caused it. If you throw a RuntimeException of some sort and the user doesn't catch it, then the user will get a nice clear stack trace, and the thread will probably end. In my experience, the latter is much easier to debug.

Also, if you return null, that usually must be checked for in the method that called your method. It's harder to check it from somewhere higher in the call stack. If you throw a RuntimeException, it's easy to catch that from anywhere in the call stack, without making any changes to other methods. So this gives you more flexibility.

[RKB]: You can even print out the same diagnostic information in the catch block before returning null.

Well most importantly, in EFH's example he didn't print out diagnostic info. The stack trace, and possibly the file name, are now lost. I do not regard this information as optional, except in the rare case that the coder has determined that the "exception" is entirely expected, and not worth reporting to anyone. That might make sense for a FileNotFoundEsception in some cases, but not for a more general IOException, I think.

Also if you print the stack trace from within the method, you are forcing the calling method to use your method of error reporting. Many programs usea logger of some sort, while others just write to System.out or System.err. But if you print or log from within the method, the calling code doesn't get to choose where to print the log message. This can be very confusing if all other errors appear in a log file, byt this error goes to standard error (which may not be monitored in some cases). And if you treat the error as recoverable, then the end user doesn't need or want to know about it - so printing a stack trace on the screen is rude.

In short, how and where to print an error message should be up to the code that calls the method. Inside the method, we just need to make sure that important information (like the stack trace) is not lost.
[ December 09, 2007: Message edited by: Jim Yingst ]
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's really great. Thank you so much for the beautiful explanation Jim.

I do need a clarification on one of the lines what you said,


It's harder to check it from somewhere higher in the call stack. If you throw a RuntimeException, it's easy to catch that from anywhere in the call stack, without making any changes to other methods.


What exactly do you mean to say 'somewhere higher in the call stack'? do we have a control in the call stack trace as where we want to pick up?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The call stack is how a processor keeps track of methods calling other methods. If method a() calls b() which calls c() which calls d() which calls e(), then a() and b() are higher in the call stack than c(), and d() and e() are deeper in the call stack than c(). It's basically the same as the stack trace, except that higher in the call stack == closer to the bottom of the stack trace, and deeper in the call stack == closer to the top of the stack trace. That's just the way the terminology evolved.

Anyway, if method e() throws a RuntimeException, then you can catch it in d(), or in c(), or in b(), or in a(). You can catch it in any method that is higher in the call stack. Whichever method is most convenient, or most logical. The nice thing about using RuntimeExceptions is that you don't have to alter the other methods at all to do this. They don't need throws clauses. Of course the down side is that means that programmers may not be aware that they can (and perhaps should) catch this exception somewhere. That's why there are long discussions of the merits of checked vs. unchecked exceptions, in the links I provided.
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's really so nice of you Jim. I have got it

Thank you again.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!