Java Exception Handling

In this tutorial, you will learn to handle exceptions in Java with the help of examples. To handle exceptions, we will use try…catch…finally blocks.

In the last tutorial, we learned about exceptions. Exceptions are surprising functions that happen during program execution.


Catching and handling exceptions

In Java, we use the exception controller segments to try, catch and finally blocks to handle exceptions.

To catch and handle an exception, we place the try…catch…finally block around the code that may create an exception. The final block is optional.

The syntax for try…catch…finally is:

try {
  // code
} catch (ExceptionType e) { 
  // catch block
} finally {
  // finally block
}

Java try…catch block

The code that might generate an exception is placed in the try block.

Every try block should be immediately followed by the catch or finally block. When an exception occurs, it is caught by the catch block that immediately follows it.

catch blocks cannot be used alone and must always be preceded by a try block.

Example 1: try…catch blocks

class Main {
  public static void main(String[] args) {

    try {
      int divideByZero = 5 / 0;
      System.out.println("Rest of code in try block");
    } catch (ArithmeticException e) {
      System.out.println("ArithmeticException => " + e.getMessage());
    }

  }
}

Output

ArithmeticException => / by zero

In the example,

  • We have divided a number by 0 inside the try block. This produces an ArithmeticException.
  • When the exception occurs, the program skips the rest of the code in the try block.
  • Here, we have created a catch block to handle ArithmeticException. Hence, the statements inside the catch block are executed.

If none of the statements in the try block generates an exception, the catch block is skipped.


Multiple Catch blocks

For each attempt block, there can be at least zero catch blocks.

The contention sort of each catch block shows the type of exception that can be handled. Numerous catch blocks allow us to handle each exception differently.

Example 2: Multiple catch blocks

class ListOfNumbers {
  public int[] arrayOfNumbers = new int[10];

  public void writeList() {

    try {
      arrayOfNumbers[10] = 11;
    } catch (NumberFormatException e1) {
      System.out.println("NumberFormatException => " + e1.getMessage());
    } catch (IndexOutOfBoundsException e2) {
      System.out.println("IndexOutOfBoundsException => " + e2.getMessage());
    }

  }
}

class Main {
  public static void main(String[] args) {
    ListOfNumbers list = new ListOfNumbers();
    list.writeList();
  }
}

Output

IndexOutOfBoundsException => Index 10 out of bounds for length 10

In this example, we have declared an array of integers arrayOfNumbers of size 10.

We know that an array index always starts from 0. So, when we try to assign a value to index 10, an IndexOutOfBoundsException occurs because the array bounds for arrayOfNumbers is 0 to 9.

When an exception occurs in the try block,

  • The exception is thrown to the first catch block. The first catch block does not handle an IndexOutOfBoundsException, so it is passed to the next catch block.
  • The second catch block in the above example is the appropriate exception handler because it handles an IndexOutOfBoundsException. Hence, it is executed.

Java finally block

For each try block, there can be only one finally block.

The finally block is optional. However, if defined, it is always executed (even if the exception doesn’t occur).

If an exception occurs, it is executed after the try…catch block. If no exception occurs, it is executed after the try block.

The basic syntax of finally block is:

try {
  //code
} catch (ExceptionType1 e1) { 
  // catch block
} catch (ExceptionType1 e2) {
 // catch block
} finally {
  // finally block always executes
}

Example 3: finally block

class Main {
  public static void main(String[] args) {
    try {
      int divideByZero = 5 / 0;
    } catch (ArithmeticException e) {
      System.out.println("ArithmeticException => " + e.getMessage());
    } finally {
      System.out.println("Finally block is always executed");
    }
  }
}

Output

ArithmeticException => / by zero
Finally block is always executed

In this example, we have divided a number by 0. This throws an ArithmeticException which is caught by the catch block. The finally block always executes.

Having a finally block is considered a good practice. It is because it includes important cleanup code such as:

  • code that might have been accidentally skipped by return, continue or break statements
  • closing a file or connection

We have referenced that at last consistently executes and that is generally the situation. However, there are a few situations when an at last square doesn’t execute:

  • Use of System.exit() method
  • An exception occurs in the final block
  • The death of a thread

Example 4: try, catch and finally blocks

Let’s take an example where we try to create a new file using FileWriter and write data to it using PrintWriter.

import java.io.*;

class ListOfNumbers {
  private int[] list = new int[10];

  public ListOfNumbers() {
    // storing integer values in the list array
    for (int i = 0; i < 10; i++) {
      list[i] = i;
    } 	
  }

}

  public void writeList() {
    PrintWriter out = null;

    try {
      System.out.println("Entering try statement");

      // creating a new file OutputFile.txt
      out = new PrintWriter(new FileWriter("OutputFile.txt"));

      // writing values from list array to the new created file
      for (int i = 0; i < 10; i++) {
        out.println("Value at: " + i + " = " + list[i]);
      }
    } catch (IndexOutOfBoundsException e1) {
      System.out.println("IndexOutOfBoundsException => " + e1.getMessage());
    } catch (IOException e2) {
      System.out.println("IOException => " + e2.getMessage());
    } finally {
      // checking if PrintWriter has been opened
      if (out != null) {
        System.out.println("Closing PrintWriter");
        out.close();
      } else {
        System.out.println("PrintWriter not open");
      }
    }

  }
}

class Main {
  public static void main(String[] args) {
    ListOfNumbers list = new ListOfNumbers();
    list.writeList();
  }
}

When you run this program, there are two possibilities that may occur:

An exception occurs in the try block
The try block executes normally

An exception can happen while making new FileWriter. It tosses an IOException if the document indicated can’t be made or written to.

At the point when an exemption happens, we will get the accompanying output.

Entering try statement
IOException => OutputFile.txt
PrintWriter not open

When exception doesn’t occur and the try block executes normally, we will get the following output.

Entering try statement
Closing PrintWriter

An OutputFile.txt is created and will have the following content:

Value at: 0 = 0
Value at: 1 = 1
Value at: 2 = 2
Value at: 3 = 3
Value at: 4 = 4
Value at: 5 = 5
Value at: 6 = 6
Value at: 7 = 7
Value at: 8 = 8
Value at: 9 = 9

Working of try…catch…finally in Detail

We should attempt to comprehend the flow of exception handling in detail with the help of the above example.

The above figure describes the flow of program execution when an exception occurs while creating a new FileWriter.

  • To get to the method where the exception occurs, the main method calls the writeList() method which then calls the FileWriter() method to create a new OutputFile.txt file.
  • When an exception occurs, the runtime system skips the rest of the code in the try block.
  • It starts searching through the call stack in reverse order to find an appropriate exception handler.
  • Here, FileWriter does not have an exception handler, so runtime system checks the next method in the call stack i.e writeList.
  • The writeList method has two exception handlers: one that handles IndexOutOfBoundsException and another that handles IOException.
  • The system then goes through these handlers in sequential order.
  • The first handler in this example handles IndexOutOfBoundsException. This does not match the IOException thrown by the try block.
  • So, the next handler is checked which is the IOException handler. This matches the type of exception thrown so the code in the catch block is executed.
  • After the exception handler executes, the finally block is executed.
  • In this scenario, since an exception occurred in the FileWriter, the PrintWriter object out was never opened and does not need to be closed.

Presently, let us guess that the exception doesn’t happen while running this program and the try block executes ordinarily. An OutputFile.txt is made and written to for this situation.

As we know, the final block is executed paying little heed to the exception handling. Since no exception happened, the PrintWriter is open and should be shut. This is finished by out.close() proclamation in the finally block.


Catching Multiple Exceptions

From Java SE 7 and later, we can now catch more than one type of exception with one catch block.

This reduces code duplication and increases code simplicity and efficiency.

Each exception type that can be handled by the catch block is separated using a vertical bar |.

Its syntax is:

try {
  // code
} catch (ExceptionType1 | Exceptiontype2 ex) { 
  // catch block
}

The attempt with-resources statement

The attempt with-resources statement is an attempt articulation that has at least one resource declaration.

Its syntax is:

try (resource declaration) {
  // use of the resource
} catch (ExceptionType e1) {
  // catch block
}

The resource is an object to be closed at the finish of the program. It must be announced and instated in the attempt explanation.

Let’s take an example.

try (PrintWriter out = new PrintWriter(new FileWriter(“OutputFile.txt”)) {
  // use of the resource
}

The try-with-resources statement is likewise referred to as automatic resource management. This announcement consequently closes all the resources toward the finish of the statement.


Thanks for reading! We hope you found this tutorial helpful and we would love to hear your feedback in the Comments section below. And show us what you’ve learned by sharing your photos and creative projects with us.