Chapter 11 - Java for Beginners Course

Multiple catch blocks

By: Andres Perez

Until now, we have used try/catch blocks with at most one catch block to capture the exceptions thrown in the try block. But, in Java it is possible to use more than one catch block for a single try block. This allows us to catch and handle exceptions of more than one type (including all of its subclasses), and handle each in a different way.

Order of the catch blocks

When using multiple catch blocks, if an exception is thrown, the blocks are considered in the same order as they appear in the code. So if one exception matches the type of more than one catch block (remember that each catch block also catches all of the subclasses of the specified exception type), only the topmost block is executed.

For example, the following program considers the possible exceptions that might occur when dividing two elements of an ArrayList:

List<Integer> list = new ArrayList<>();
list.add(36);
list.add(4);
list.add(0);
try {
    int result = list.get(0) / list.get(1); // 36/4
    System.out.println("The result is: " + result);
} catch(IndexOutOfBoundsException e) {
    System.out.println("An IndexOutOfBoundsException occurred: " + e.getMessage());
} catch (ArithmeticException e) {
    System.out.println("An ArithmeticException occurred: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Some other exception occurred: " + e.getClass());
}

Output:

The result is: 9

But, if we select an index that doesn’t exist in the ArrayList:

List<Integer> list = new ArrayList<>();
list.add(36);
list.add(4);
list.add(0);
try {
    int result = list.get(0) / list.get(5); // Index 5 is out of bounds
    System.out.println("The result is: " + result);
} catch(IndexOutOfBoundsException e) {
    System.out.println("An IndexOutOfBoundsException occurred: " + e.getMessage());
} catch (ArithmeticException e) {
    System.out.println("An ArithmeticException occurred: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Some other exception occurred: " + e.getClass());
}

Output:

An IndexOutOfBoundsException occurred: Index: 5, Size: 3

An exception is captured by the first catch block.

Moreover, if we select 0 (the 3rd element in the list) as the divisor:

List<Integer> list = new ArrayList<>();
list.add(36);
list.add(4);
list.add(0);
try {
    int result = list.get(0) / list.get(2); // 36/0
    System.out.println("The result is: " + result);
} catch(IndexOutOfBoundsException e) {
    System.out.println("An IndexOutOfBoundsException occurred: " + e.getMessage());
} catch (ArithmeticException e) {
    System.out.println("An ArithmeticException occurred: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Some other exception occurred: " + e.getClass());
}

Output:

An ArithmeticException occurred: / by zero

Now, the exception is captured by the second catch block.

In the case that an exception is thrown, but it isn’t of type IndexOutOfBoundsException or ArithmeticException, it will be captured by the last catch block, as Exception is a superclass for all exceptions. For example, if the ArrayList is null, a NullPointerException will be thrown:

List<Integer> list = null;
try {
    int result = list.get(0) / list.get(1); // list is null
    System.out.println("The result is: " + result);
} catch(IndexOutOfBoundsException e) {
    System.out.println("An IndexOutOfBoundsException occurred: " + e.getMessage());
} catch (ArithmeticException e) {
    System.out.println("An ArithmeticException occurred: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Some other exception occurred: " + e.getClass());
}

Output:

Some other exception occurred: class java.lang.NullPointerException

In this way we can capture all exceptions while handling some in a specific way. It is important that you place the catch for the most specific exceptions first, to avoid a superclass capturing more exceptions than it should.

In our previous example, if we place the catch( Exception e ) block first, it will capture all exceptions thrown in the try block, as all of them are subclasses of Exception. If this happens, our other catch blocks will never be invoked, as they will never capture any exceptions.

Multiple exception types in a single catch block

Starting from Java 7, it is possible to catch more than one type of exception with the same catch block. This is done by placing all of the exception types in the argument for catch, separated by a pipe symbol, |. For example, if we wanted to have just one exception handler in the previous example for the IndexOutOfBoundsException and ArithmeticException types, we can do it in the following way:

List<Integer> list = new ArrayList<>();
list.add(36);
list.add(4);
list.add(0);
try {
    int result = list.get(0) / list.get(5); // Index 5 is out of bounds
    System.out.println("The result is: " + result);
} catch(IndexOutOfBoundsException | ArithmeticException e) {
    System.out.println("An IndexOutOfBoundsException or ArithmeticException occurred: " + e.getMessage());
} catch(Exception e) {
    System.out.println("Some other exception occurred: " + e.getClass());
}

Output:

An IndexOutOfBoundsException or ArithmeticException occurred: Index: 5, Size: 3

In this case, an IndexOutOfBoundsException was thrown and it was captured by the first catch block. Now let’s see what happens when we divide by 0 and an ArithmeticException is thrown:

List<Integer> list = new ArrayList<>();
list.add(36);
list.add(4);
list.add(0);
try {
    int result = list.get(0) / list.get(2); // 36/0
    System.out.println("The result is: " + result);
} catch(IndexOutOfBoundsException | ArithmeticException e) {
    System.out.println("An IndexOutOfBoundsException or ArithmeticException occurred: " + e.getMessage());
} catch(Exception e) {
    System.out.println("Some other exception occurred: " + e.getClass());
}

Output:

An IndexOutOfBoundsException or ArithmeticException occurred: / by zero

As expected, the exception was again captured by the same catch block.

A single catch block can capture more than two types of exceptions. For example by using: catch( IndexOutOfBoundsException | ArithmeticException | IllegalArgumentException | NullPointerException e).