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.
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:
[ December 09, 2007: Message edited by: Jim Yingst ]
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?
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 ]
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?
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.