Why Do We Use Finally Blocks

Why do we use finally blocks?

  • What happens if an exception you're not handling gets thrown? (I hope you're not catching Throwable...)
  • What happens if you return from inside the try block?
  • What happens if the catch block throws an exception?

A finally block makes sure that however you exit that block (modulo a few ways of aborting the whole process explicitly), it will get executed. That's important for deterministic cleanup of resources.

Why use the finally keyword?

Short Answer

Finally blocks are guaranteed to run no matter what happens inside of the try and catch blocks, before allowing the program to crash.

This is sort of explained here: https://www.php.net/manual/en/language.exceptions.php though the explanation isn't particularly detailed.

Some More Detail

One example that comes to the top of my head is if you are dealing with input/output streams or something similar that has to be closed after use in order to avoid a memory leak. To use your example:

try {
memoryUser.startReading(someFileOrSomething);
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
invisibleBug.whoops(); // i.e. something goes wrong in this block
}

memoryUser.Close(); // because something went wrong in the catch block,
// this never runs, which, in this case, causes a memory leak

In this case, wrapping the memoryUser.Close(); in a finally block would ensure that that line would run before the rest of the program exploded, preventing the memory leak even in an otherwise catastrophic failure.

TL;DR

So a lot of the time, people put the finally block there to ensure an important line runs, even if they overlooked something in the catch blocks. This is how I've always seen it used.

Hopefully this helps :)

Why use finally

They differ if

  • the try-block completes by throwing a java.lang.Throwable that is not a java.lang.Exception, for instance because it is a java.lang.Error such as AssertionError or OutOfMemoryError.
  • the try-block completes abruptly using a control flow statement such a continue, break or return
  • the catch-block completes abruptly (by throwing any throwable, or using a control flow statement)

More generally, the java language guarantees that a finally block is executed before the try-statement completes. (Note that if the try-statement does not complete, there is no guarantee about the finally. A statement might not complete for a variety of reasons, including hardware shutdown, OS shutdown, VM shutdown (for instance due to System.exit), the thread waiting (Thread.suspend(), synchronized, Object.wait(), Thread.sleep()) or being otherwise busy (endless loops, ,,,).

So, a finally block is a better place for clean-up actions than the end of the method body, but in itself, still can not guarantee cleanup exeuction.

Do you really need the 'finally' block

I think willcode comes the closest to expressing the key point here, and probably everyone means it but are not clear.

The problem is there is indeed something very wrong with what you are asking: "If i write all the statements after catch block instead of writing them into finally block then then would there be anything wrong?"

If you write all the statements after the catch block, what you are implying is that

1) You will always catch the exception.

2) You will always continue on to the next statements after you catch the exception.

This implies that you will always continue the execution "normally" after an exception, which is generally something you never in fact want to do.

Exceptions should be just that - exceptional. If you can in fact handle an exception, it is always better to write your code to consider those conditions first and not lead to an exception at all. If you follow this model then exceptions are truly exceptional - conditions you could not anticipate or at most not fix. Really not anticipate is what you should work towards. This means in general you are unable to handle true exceptions, which also means you should not just continue execution, often you end the application instead.

What is normally done is you allow an error to propagate back up the call stack. Some say this is done on the off chance that someone higher up in the chain may be able to handle it. I would say that essentially never happens, there are two real purposes to do this. One it may be something the user can fix, if there is one. So you propagate the error back up until you get to where you can report it to the user. Or two, a user cannot fix it but you want to get the entire call stack for debugging. Then you catch it at the top to fail gracefully.

The finally block now should have more meaning to you. As everyone says it always runs. The clearest use of a finally is really in a try... finally block. What you are now saying is if the code runs fine, great. We still need to do some clean up and the finally always executes then we move on. But if an exception occurs, we now really need that finally block because we may still need to do some clean up, but we are no longer catching the exception here so we are not going to be moving on anymore. The finally block is essential to ensure that clean up occurs.

The idea of an exception always halting execution may be hard for someone to grasp until they have a certain amount of experience, but that is in fact the way to always do things. If an error happened, either it was so minor you should have accounted for it to begin with, or else there are just more and more errors waiting to happen down the line.

"Swallowing" errors - catching them and moving on is the worst thing you can do because your program becomes unpredictable and you cannot find and fix bugs.

Well written code will contain as many try ... finally blocks as are necessary to make sure that resources are always released no matter the outcome. But well written code generally contain only a small number of try ... catch blocks that exist primarily to allow an application to fail as gracefully as possible, or defer to the user, which means at least always pass a message to the user etc. But you usually do not just catch an error and keep going.

What is the need of finally block in java?

As per oracle Documentation:

The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.

For detail read this article.

Now answer to your below question:

Now the above code handles all the exceptions. So, why do I need a finally block here? Instead of writing something in finally block I can write that outside the try-catch block,Both are same.

Suppose you are re-throwing an exception from a catch block, in such a condition non of the codes after that catch block will execute but if you add a finally block all the codes inside finally block will execute before re-throwing of the exception from the catch block.

Why do we need the finally clause in Python?

It makes a difference if you return early:

try:
run_code1()
except TypeError:
run_code2()
return None # The finally block is run before the method returns
finally:
other_code()

Compare to this:

try:
run_code1()
except TypeError:
run_code2()
return None

other_code() # This doesn't get run if there's an exception.

Other situations that can cause differences:

  • If an exception is thrown inside the except block.
  • If an exception is thrown in run_code1() but it's not a TypeError.
  • Other control flow statements such as continue and break statements.

Why use finally instead of code after catch

Because if an exception gets thrown no code after the try block is executed unless the exception is caught. A finally block is always executed no matter what happens inside your try block.

What is the purpose of finally in try/catch/finally

In your example, it doesn't make a whole lot of difference.

Picture this, though:

    try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch (SomeOtherException e)
{
Console.WriteLine("{0} Caught exception #1.", e);
}
finally
{
Console.WriteLine("Executing finally block.");
}

Console.WriteLine("Executing stuff after try/catch/finally.");

In this case, the catch won't catch the error, so anything after the whole try/catch/finally will never be reached. However, the finally block will still run.



Related Topics



Leave a reply



Submit