Java try catch finally

Java try, catch and finally blocks help in writing the application code which may throw exceptions in runtime and gives us a chance to either recover from exceptions by executing alternate application logic or handle the exception gracefully to report back to the user. It helps in preventing ugly application crashes.

Note that it is recommended to use the try-with-resources block everytime it is possible to use.

1. The Basics

Before going deep into the concept, let us go through the very basic understanding of try-catch blocks and their syntax.

1.1. try

The try block contains the application code which is expected to work in normal conditions. For example, reading a file, writing to databases or performing complex business operations.

A try block is written with the try keyword followed by the curly braces.

try {
    //application code
}

1.2. catch

The optional catch block(s) follows the try block and MUST handle the checked exceptions thrown by the try block and any possible unchecked exceptions.

try {
    //code
}
catch(Exception e) {
    //handle exception
}

An application can go wrong in N different ways. That’s why we can associate multiple catch blocks with a single try block. In each catch block, we can handle one or more specific exceptions in a unique way.

When one catch block handles the exception, the next catch blocks are not executed. Control shifts directly from the executed catch block to execute the remaining part of the program, including the finally block.

try {
    //code
}
catch(NullPointerException e) {
    //handle exception
}
catch(NumberFormatException e) {
    //handle exception
}
catch(Exception e) {
    //handle exception
}

1.3. finally

An optional finally block gives us a chance to run the code which we want to execute EVERYTIME a try-catch block is completed – either with errors or without any errors.

The finally block statements are guaranteed execution even if we fail to handle the exception successfully in catch block.

try {
	//open file
    //read file
}
catch(Exception e) {
    //handle exception while reading the file
}
finally {
	//close the file
}

1.4. Only the try block is Mandatory

Please note that only try block is mandatory while catch and finally blocks are optional. With a try block, we can use either a catch block or finally block as needed.

It is possible to have below given both combinations in Java. Both versions are valid.

try {

}
catch(Exception e) {

}
try {

}
finally {

}

2. How an exception floats in Java?

Under normal circumstances, when there is an exception occurred during runtime, JVM wraps the error information in an instance of the sub-type of Throwable. This exception object is similar to other Java objects and has fields and methods.

Only difference is that JVM checks their presence and passes control to catch block which can handle this exception type or its parent class types.

try catch finally flow
try catch finally flow

When in the application, there is no catch block found for an exception, the uncaught exception is handled by a default exception handler at JVM level. It reports the exception to the user and terminates the application.

3. Different execution flows with try, catch and finally blocks

Let’s see some examples to understand how the executions will flow in different cases.

3.1. try, catch and finally blocks – NO exception occurred

If there is no exception occurred, then JVM will execute only finally block. The catch block will be skipped.

try
{
    System.out.println("try block");
}
catch (Exception e)
{
    System.out.println("catch block");
}
finally
{
    System.out.println("finally block");
}

Program output.

try block
finally block

3.2. try, catch and finally blocks – exception occurred

If there is an exception occurred in try block, then JVM will execute catch block first and then finally block.

try
{
    System.out.println("try block");

    throw new NullPointerException("Null occurred");
}
catch (Exception e)
{
    System.out.println("catch block");
}
finally
{
    System.out.println("finally block");
}

Program output.

try block
catch block
finally block

3.3. try and finally blocks – exception NOT handled

If the exception is not handled by any provided catch block, the JVM default exception handler handles it. In this case, finally block will be executed followed by the default exception handling mechanism.

try
{
    System.out.println("try block");

    throw new NullPointerException("Null occurred");
}
finally
{
    System.out.println("finally block");
}

Program output.

try block
finally block

Exception in thread "main"
java.lang.NullPointerException: Null occurred
	at com.howtodoinjava.Main.main(Main.java:12)

3.4. try, catch and finally blocks – multiple catch blocks

If there are multiple catch blocks associated with the try block, then the exception is handled by the first catch block in the sequence which can handle the exception type or its parent types.

For example, a catch block handling IOException, can handle the exceptions of type FileNotFoundException also because FileNotFoundException extends IOException.

try
{
    System.out.println("try block");

    throw new NullPointerException("null occurred");
}
catch (NumberFormatException e)
{
    System.out.println("catch block 1");
}
catch (NullPointerException e)
{
    System.out.println("catch block 2");
}
catch (Exception e)
{
    System.out.println("catch block 3");
}
finally
{
    System.out.println("finally block");
}

Program output.

try block
catch block 2
finally block

3.5. try, catch and finally blocks – Exception is thrown from catch block

There may be cases when there is an exception while handling another exception in catch block. How will it handled?

In case of exception in the catch block, the execution is transferred to finally block (if any) associated with the respective catch block. Then the exception is propagated in the method call stack to find a catch block that can handle this exception.

If such catch block is found then exception is handled, else JVM default exception handler handles the exception and terminates the application.

try
{
    System.out.println("try block");

    throw new NullPointerException("NullPointerException occured");
}
catch (NullPointerException e)
{
    System.out.println("catch block 1");

    throw new NumberFormatException("NumberFormatException occurred");
}
catch (Exception e)
{
    System.out.println("catch block 2");
}
finally
{
    System.out.println("finally block");
}

Program output.

try block
catch block 1
finally block

Exception in thread "main"
java.lang.NumberFormatException: NumberFormatException occurred
	at com.howtodoinjava.Main.main(Main.java:18)

4. Java 7 try-with-resources

For AutoCloseable resources, such as streams, Java SE 7 introduced try-with-resources statements which is recommended ways to handle exceptions in mentioned scenarios. In this approach, we are not required to close the streams and JVM does it for us. It eliminates the need for finally blocks.

In try-with-resources, a resource is opened in try block inside small brackets and finally block is completely gone.

try (BufferedReader br = new BufferedReader(new FileReader("C:/temp/test.txt")))
{
    String sCurrentLine;
    while ((sCurrentLine = br.readLine()) != null)
    {
        System.out.println(sCurrentLine);
    }
}
catch (IOException e)
{
    e.printStackTrace();
}

Happy Learning !!

Comments

Subscribe
Notify of
guest
7 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.