Its pretty simple. Lets consider the following piece of code:
Example 1 Example 2 Now, if I understand you right, your doubt is, when we can just code as in Example 2, why do we need to have a code as in Example 1 by including a finally block. Is that so? Well, if yes, then the answer is pretty simple.
You should always keep in mind that anything that you include in a finally block will ALWAYS be executed no matter what. When I say no matter what, I mean, that block of code will be executed whether or not an exception is thrown. If you code as in Example 2, that is, without any finally block, then in case an IOException is thrown during a call to the read() method, the statement
br.close(); will never be executed! In this case, the resource that you have opened up for reading will not be closed and your app will still hold it.
If you include a finally block, however, you will be forcing the resource to be closed even if an exception is thrown.
The output of Example 1 in case an exception is thrown will be:
About to call read()
IOException thrown
Inside the finally block, about to close file
The output of Example 1 in case of no exception thrown will be:
About to call read()
Inside the finally block, about to close file
The output of Example 2 in case an exception is thrown will be:
About to call read()
IOException thrown
The output of Example 2 in case of no exception thrown will be:
About to call read()
About to close file
So you see, the file will never be closed in the second case (Example 2). So, under such situations where you HAVE to do something critical even if an exception gets thrown, you have to use a finally block.
Now you get it?