Post a Comment
(Arghh! It working in the preview! Any change of an intelligent <code> tag support, it'd be okay if it chopped excessively long lines)
A powerful part of the exception mechanism is the finally block. This is ALWAYS executed, whether your program hits an error or not. Thus it is often used to free resources (dynamically allocated memory, database connections, network connections or files).
e.g. (from Java)
public static void copy(String[] args)
{
File inputFile = null, outputFile = null;
try
{ inputFile = new File("farrago.txt");
outputFile = new File("outagain.txt");
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
}
catch (FileNotFoundException fnfe)
{ // do stuff
}
catch (IOException e)
{ // do stuff
}
catch (Exceptione e)
{ // do stuff
}
finally
{ // whether the program worked or threw an
// exception, we close the files
in.close();
out.close();
}
}
In this way you're guaranteed to close your files, no matter what happens. These finally blocks are incredibly useful, and are essential if you start doing socket or DB programming in modern OOP languages like Java or C#. They're also essential to avoid memory leaks if you're dealing with dynamic memory allocation like in C++ or Delphi.
This is kinda embarrassing, but the finally block should be
finally
{ if (inputFile != null) inputFile.close();
if (outputFile != null) outputFile.close();
}
So why can't you just put the close statements after the catch blocks? They will be executed with or without exceptions.
in .Net, no code outside of a "catch" statement is guaranteed to run unless it's in a "finally" block. Just comes w/ the framework, plus this lends itself to better coding practices.
You may exit the method in a catch block, or you may quit the program in a catch block. Whatever you do though, the finally block will always get called.
Also, as Jayson said, it's considered better programming practice, it makes it explicit what resources you're using and protects against other programmers altering, e.g. exception handlers, in the future.
exception in smalltalk are way better, cause they have #resum().
This mean that you can restart the processing from the exact method instead of a spurious block.
Even, exception's statement modifer are really useful, too bad common .net languages do not use them :/
Please let's not turn this into one more "language war" 
in most instances, you have to put try/catch around close methods, because they throw IOException. this, in java, is *the* correct way:
FileReader in = null;
try {
in = new FileReader( "filename" );
// do stuff
} catch ( IOException e ) {
// print error
} catch ( FileNotFoundException e ) {
// print error
} finally {
if ( in != null ) {
try {
in.close();
} catch ( IOException e ) {
// print file close error
}
}
}
I did not meant to be rude, and I beg your pardon
I just believe that Exception#resume() is a wonderful tool, and I'd like to see it in more environments.
BTW people may argue that they are not good, I just wonder why.
Say, Ruby has first class reified continuations and it is quite easy to write a ResumableException class, yet this is not in the standard Exception's , maybe matz has an answer :/
Only last week, I wrote about exceptions vs. error codes in my blog. I think a lot of times exception classes are created and exceptions thrown where only returning a status code would be the right thing to do.
http://www.livejournal.com/~mannu/164080.html
>This is kinda embarrassing, but the finally block should be
>finally
>{ if (inputFile != null) inputFile.close();
>if (outputFile != null) outputFile.close();
>}
Well, that works. But this form is much cleaner:
try{
inputFile = new File("farrago.txt");
outputFile = new File("outagain.txt");
try{
}finally{
inputFile.close();
outputFile.close();
}
catch(IOException e){
blahblah
}
The key is you don't need all this if blah!=null business with the above approach. When you open a file or resource, always code your finally at that point. If an exception is throws on allocation/opening the resource your variables will stay null and you will not enter the try-finally block.
This is ALWAYS executed
Well that's not true:
try
{
//do something here
catch(Exception e)
{
//unrecoverable error, we loose
System.exit(1);
}
finally
{
// all resorces doesn't get cleaned
System.out.println("This is not executed in case of an exception");
}
yeah, thats called "who guards the guards" scheme..
I find it surprising that neither the article nor the comments have mentioned the using block yet. It can greatly clean up code and simplify resource cleanup:
using (FileStream input = File.OpenRead ("input.txt")) {
____using (FileStream output = File.OpenWrite ("output.txt")) {
________// copy file contents
________byte[] buffer = new byte[256];
________int nread;
________while ((nread = input.Read (buffer, 0, buffer.Length)) != -1) {
____________output.Write (buffer, 0, nread);
________}
____}
}
(My apologies for using underscores for spaces, but it's more legible than or not providing any indentation...)
No finally blocks, no worries about exceptions or resource cleanup, just plain code. Of course, if an exception is generated the exception will escape this code block (unlike the original Java version, which would swallow all exceptions), but the resources will still be disposed of cleanly, whether or not an exception is generated.
As in C++, the cleanest and most maintainable C# code doesn't use try/catch explicitly for resource cleanup. C++ instead uses block-scoped objects with destructors, and C# offers the using block to simplify resource management. It would be advisable to use it whenever possible, to help remove code errors and other embarassments.
Finally, by implementing the System.IDisposable interface, you can implement your own resource cleanup strategies, which can be used for such esoteric things as locks with timeouts.
See also:
http://www.interact-sw.co.uk/iangblog/2004/03/23/locking
http://blogs.msdn.com/ericgu/archive/2004/03/28/100872.aspx
throwing null pointer exceptions is bad practice, nor should you nest the try in that way. i disagree. mainly because i, and my professors shun anything but that try/catch/finally/try/catch system
"(Note: This article won the OSNews Aspire competition a few weeks ago.)"
The poor writing and editing make me wonder what standards the OSNews Aspire competition adheres to. The technical content is lightweight enough, but the article is made much worse by horrible grammar and writing.
The rules of English composition are no more a matter of opinion or "style" than Java syntax is. Programmers should put as much effort into communicating with other people and less into showing off their mastery of technology.
Did you say:
"[i]Programmers should put as much effort into communicating with other people and less into showing off their mastery of technology.[i]"
I'm sure a master of grammar like yourself meant to say:
"[i]Programmers should put more effort into communicating with other people and less into showing off their mastery of technology.[i]"
Have a nice day
> but the article is made much worse by horrible grammar and writing.
As we explain in the competition, grammar does not matter, content does. This way, non-english people can also participate to our competition, otherwise, we discriminate, and that's not never good.
I have a new problem with Exceptions: I need to manage the exception but I don't have an error code to compare with, just messages. I can check a message to see if it has "timeout" then instruct my code to try again later, however, if the message is "not found" then I want to rethrow the exception or log it. This can work fine, but the real problem comes when I install this on a system that produces exception strings in another language like Chinese, then I can no longer catch and manage using the message string. Anyone, know how to handle this?
Different exceptions should have different types. That way, you can check the exception type instead of checking the message.
For your scenario, the throwing code should throw FileNotFoundExceptions and TimeoutExceptions (and any other distinct type which makes sense). This permits code like:
bool run = true;
int attempts = 0;
while (run) {
____try {
________FunctionThatThrows ();
____}
____catch (FileNotFoundException e) {
________// don't bother retrying
________run = false;
____}
____catch (TimeoutException e) {
________// If it timed out, try again, but only re-try 5 times
________if (++attempts > 5) run = false;
____}
____catch (Exception e) {
________// unknown exception; don't retry
________run = false;
____}
}
Ah yes, we really should use "WTF?????" or "WTF!!!! Why is this still happening?"
How would there be a null pointer excpetion?
Your and your profs don't understand exception handling I guess.
try{
File file = new File();
try{
// use the file here
}
catch(IOException e)
{
// log or rethrow, or whatever here
}
finally{
file.close();
}
catch(FileCreateException fe)
{
// handle whatever the File open exceptions are here
}
Where are you going to get a null pointer exception in this scheme?
If an exception is thrown in the resource allocation (new File()), then execution will stop there and proceed to the catch FileCreateException. This is how it's done by people who know what they are doing, I didn't invent it.
In defense of both of you, give 10 developers the same problem, you will get at least 11 different solutions. Both ways work, it's just a matter of style; is one way any better than the other? Well that would depends on your definition of better. Going the ultra nested try/catch/finally route eliminates the need for null pointer checking. Adding the null pointer checking eliminates the need for an nested level of try, et. al People that know what they are doing do it both ways. I've yet to see a solid argument for either side clearly showing one way it better than another. If some one has one, I liked to take a read
Doing the null checks is more error prone. and less clean. that's it. the other way does work though.
He was saying my approach would throw null pointer exceptions though... and clearly it won't. The reason people use the omnivector approach is 1) they don't realize that the variable assignment doesn't happen when an exception is thrown 2) they don't undertand that execution ends at the point of the exception and either leaves the method or goes straight to the catch/finally block.




