Question

Every documentation I can find for the finally part of a try-catch-finally construct is the same: Code within the finally block runs whether or not an exception occurred, and it is useful for putting cleanup code.

My question is... why?

I mean, how is this:

try {
    doSomething();
}
catch( e) {
    somethingFailed(e);
}
finally {
    cleanupSomething();
}

any better than this:

try {
    doSomething();
}
catch( e) {
    somethingFailed(e);
}
cleanupSomething();

Put another way, how is finally any different to just continuing on?

Was it helpful?

Solution

Finally is actually very useful. It is definitely a worthy tool to have around, as it essentially works to protect resources that must be managed without waiting for the garbage collector. There are other uses, but this is its primary one.

Why should we use it though? Why not just place the disposal after the catch statement (assuming all exceptions were caught)?

There is a very good reason for this, and that is for when control leaves the try statement. If this occurs, for any reason, finally will get hit before control leaves. So, for example, if a return, continue, break, goto, or an exception if not caught -- if any of that happens in the try block finally will execute whereas the code in your post will not because control had already left. If that had been an important resource it was just leaked.

OTHER TIPS

An exception might be thrown that you don't specify to be caught.

Furthermore, I find this construct useful:

  try
  {
       // do something
  }
  finally
  {
      // cleanup, in case an exception occurs, this is always called
  }

It guarantees the cleanup code to be called, in case of exceptions that are dealt with on a higher level.

Consider the following: You want to load a big amount of data, and then process it. After the calculations of Process_The_Data() the loaded data is no longer needed.

try{
  Load_Big_Data();
  Method_That_Fails_Always();
  Process_The_Data();
}
catch( e)
{
  // we may have no means to handle the exception so let it just pass through
}
finally
{
  Delete_The_Data();
}

If you use finally, you can be sure the Data gets deleted. Just calling Delete_The_Data() in the catch-Block is no alternative because it may be that we do not fail, but want the data to be deleted nevertheless.

If you don't use finally, the Delete_The_Data()-Method is never called, and you have no way to cleanly free your memory. This is bad.

So in conclusion: You should use finally if you try something that would create a memory leak if not cleanly deleted.

finally - in Pascal, for instance - is used because of the try statement. Here is why we use it: sometimes, a try statement will work, but only partially - and, this is, in particular, the reason for the finally. Once the try is complete after a bad "run", we may be left with partial or incomplete objects that are of no use to us (may corrupt the data; cause memory issues).

If the code fails, we want to get rid of the generated object and free the memory (reducing overhead).

An un-nested cleanupSomething() may have unintended consequences, perhaps. Too, it guarantees the finally or the cleanup will happen regardless of what happens in the larger or body code (as opposed to cleanupSomething()).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top