Things you need to remember when using finally in Java

Because Java has a Garbage collector and you donā€™t know for sure when your object will be destroyed it is tricky to do proper resource management, in comparison with C++ where objects are created on the stack or you control their lifecycle manually by new/delete operator.

To help you deal with that, theĀ finally block was introduced. Assume you have some kind of resource:

You can use this resource like this:

Running this code will produce the following output:

So here we are simulating some work with a resource which generates an exception. Because we using a finally block we release precious resource before exception is thrown further. Everyone is happy. Now let me explain what you should keep in mind when using finally. You must remember that theĀ **finally block will always be executed. **(Well, almost always. I will explain later)

What does that mean?

Exception hiding.

Consider following code.

What is happening here? We are simulating work with a resource again. But two exceptions will be generated: first inside the doWork() method and the second one when we are trying to release the resource in the finally block. Which exception will be thrown to calling code? Lets run and see:

Two exceptions are thrown. One in doWork and one in release. But you will never see the original exception anywhere. It is now completely hidden and forgotten like the days when Sun was not owned by Oracle :)

Thats why, code in the finally block should be exception safe:

And here is the output:

As you can see, the exception in Resource.doWork() is thrown outside the method.

Do not use return in finally block

Return in the finally block will also hide all exceptions and will always execute:

The code above will produce the following output:

And if any code inside try { } block throws an exception, you wont see it anywhere at all, like it never happened.

Ways to avoid executing finally block

Remember I told you that the finally block almost always executes? How can you prevent it from execution? Well, first option is old, rock solid, System.exit():

This will never print ā€œIn finally()ā€.

Second way is to call the deprecated suspend() method on a thread Ā and never call resume():

Output:

This trick does not work with threadā€™s deprecatedĀ stop() method:

Output:

As you can see, finally is executed in the thread. Interesting. So the only way to avoid execution of the finally block is to interfere with code execution flow. Otherwise, finally will be always executed.