.NET and java have try/catch (I understand C++ does also?) in VB.NET it's something like this
Try Throw New Exception("Jump to catch!") 'Wont get executed... Catch Ex as Exception 'Nothing Special Here End Try 'Regular code continues...
Why is there a "Finally" Block? If I understand correctly the following two snippets are the exact same, what am I missing?
Try 'A Catch 'B Finally 'C End Try
Try 'A Catch 'B End Try 'C
A Finally block will be executed after a try block if no exception has been thrown or after a catch if an exception was thrown. This means that a finally block can be used as 'clean up' - a place to close files or connections etc, whether an exception is thrown or not.
If a try block throws an exception and the catch block propagates the exception (throws it again), the finally clause will still execute. If the finally clause executes a return statement, it overides a thrown exception (so the exception will not be thrown; instead the return will occur).
Its for when you want to do some ultimate cleanup once no matter what but possibly throw an exception in the catch block.
psuedo-code
database_connection connection = create_connection(); // no matter what we need to close this at some point try{ something( connection ); } catch ( Whatever ... ){ throw new SomethingBroke(); } finally { connection.close(); }
So no matter what happens the connection is closed.
try { return; } finally { System.out.writeln("Hello World"); }
Hello world would be printed.
Neat, so if for some reason it tries to exit the try catch block prematurely (exit sub, new exception inside one of the catch blocks, etc) it calls that finally first, mega cool.
Note that Java (and I think C# too) have finally as well. It is just a goto to the cleaning section (say, free many allocated variables). Not really a problem in languages with garbage collector, though.
It's not really like a goto. The act of throwing the exception is more like a goto - though labelling a block by putting "mylabel:" before the opening brace, and then breaking out of that block with "break mylabel;", is even more like a goto.
The finally block will be executed at the moment the execution exits the scope of the 'try' construct (including its 'catch' clauses), no matter how it exits it. The only exception might be when the VM is shutting down or the program is exiting.
Even though the language is garbage-collected, OS resources such as files still need to be closed, and there are certain cases where the garbage collector won't free your memory: for example, you might have a static field holding a list for temporary use, and you might want the objects unliked when you've finished with the list this time round.
For an alternative solution to handling exceptions check out Ada exceptions. With Ada you simply group cases for possible exceptions that may be raised in a procedure/function at the bottom of the procedure:
1 | procedure Insert (New_Name : in Name; |
2 | New_Number : in Number) |
3 | is |
4 | … |
5 | begin |
6 | … |
7 | if New_Name = Old_Entry.A_Name then |
8 | raise Name_Duplicated; |
9 | end if; |
10 | … |
11 | New_Entry := new Dir_Node'(New_Name, New_Number,…); |
12 | … |
13 | exception |
14 | when Storage_Error => raise Directory_Full; |
15 | end Insert; |
Admittedly, that's kinda hard to read if you're not familiar Pascal style code.
How is Ada's exception handling different than Java/C#'s( or even python and ruby too )?
Note: 'catch' clauses in Java don't catch all exceptions; they just catch exceptions of the type specified, and subtypes thereof. For example
try { int x=1/0; } catch (RuntimeException e) { e.printStackTrace(); } finally { System.out.println("Clean-up code goes here"); }
The ArithmeticException will be caught because ArithmeticException is a subclass of RuntimeException.
try { int x=1/0; } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("Clean-up code goes here"); }
The ArithmeticException won't be caught because ArithmeticException is not a subclass of IOException. (In fact, I don't think the code will even compile, because IOException is a checked exception and there is no code in the 'try' block that throws one - but never mind.)
In the first case, the clean-up code would still run if it were just a statement outside the try-catch construct. In the second case, it wouldn't run if it were just a statement outside the try-catch construct. However, in both cases, it will run regardless because it is inside the finally block.
This also clarifies kazzmir's point, by illustrating that a try-catch block can specify which exceptions it wants to catch. (You can have multiple 'catch' clauses.) I can't see much of a difference either, except that Java forces you to use an explicit construct and lets you group ANY set of statements, not just ALL statements in a method.
Ada is different because you put it after the procedure ('function' in C) and it is treated kind of like a case statement.
I like Ada's the best, in fact I like how Ada does most things better, they just need to work on more libary support.
procedure Insert (New_Name : in Name;
New_Number : in Number)
is
…
begin
…
if New_Name = Old_Entry.A_Name then
raise Name_Duplicated;
end if;
…
New_Entry := new Dir_Node'(New_Name, New_Number,…);
…
exception
when Storage_Error => raise Directory_Full;
end Insert;
Looks allot like writing oracle stored procedures.
How is Ada's exception handling different than Java/C#'s
The exception code is called for any exception that arises in the procedure, so exceptions don't have to be declared or explicitly thrown, although they can be. It's like saying 'if something fails in this code I can check at the end of the block for anything that might have gone wrong'. Pretty useful for keeping the airplane from crashing.
edit;
I can't see much of a difference either, except that Java forces you to use an explicit construct and lets you group ANY set of statements, not just ALL statements in a method.
Yeah, I'll agree with that, it's similar. Ada seems quiet a lot cleaner though in my opinion.
Note that Java (and I think C# too) have finally as well.
I noted that in my first post. C# is a .NET language, and has all the same stuff VB gets afterall -- same as J#, and managed C++, along with any other language that compiles to IL code.
Note: 'catch' clauses in Java don't catch all exceptions; they just catch exceptions of the type specified, and subtypes thereof. For example
A catch in C# doesn't either, but if you catch the base type Exception, the type from which all exceptions derive, and the default catch type if none is specified, well, it only makes sense to catch any error thrown. But if you only want to catch a ThreadAbortException, then your code will only catch ThreadAbortExceptions, for example.
You can have multiple catch blocks to handle different types of exceptions.
ThreadAbortException
They still have those? My god. (In Java they're called ThreadDeath, and they're nasty.)
Michael, did my post above help clarify the purpose of 'finally'? It's not just for a catch block throwing an exception, it's for ANY flow of execution out of any part of the construct (e.g. exception thrown in the 'try' block and not caught).
The exception code is called for any exception that arises in the procedure, so exceptions don't have to be declared or explicitly thrown, although they can be. It's like saying 'if something fails in this code I can check at the end of the block for anything that might have gone wrong'. Pretty useful for keeping the airplane from crashing.
I might be misinterpreting what you're saying, but I think Visual Basic (pre-.NET) has a similar design with it's GoTo usage...
' For those that don't know, a single-quote (') is used for line comments in ' VB*. Sub x() On Error GoTo ErrorHandler ' Sub Procedure Code Goes Here... Exit: Exit Sub ErrorHandler: ' Error Handling Code Goes Here... End Sub
Ada is crap.
'{'/'}' is so much cleaner than 'begin'/'end'.