๐ŸŽ“ A1Learner
๐Ÿ”
0 of 40 lessons completed

Java Multiple Catch Blocks

A try block can carry several catch blocks, one for each failure type. Each catch block runs only for the exception type it names.

Two catches, two messages

Each try below fails in a different way. Each failure lands in the catch written for its type.

public class Main {
  public static void main(String[] args) {
    int[] numbers = {1, 2, 3};
    try {
      System.out.println(numbers[5]);
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println("index out of range");
    } catch (ArithmeticException e) {
      System.out.println("cannot divide by zero");
    }
    try {
      System.out.println(10 / 0);
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println("index out of range");
    } catch (ArithmeticException e) {
      System.out.println("cannot divide by zero");
    }
  }
}

One catch for two types

The multi-catch form lists two types joined by a vertical bar. Both failures below print the same shared line.

public class Main {
  public static void main(String[] args) {
    int[] numbers = {1, 2, 3};
    try {
      System.out.println(numbers[5]);
    } catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
      System.out.println("the operation failed");
    }
    try {
      System.out.println(10 / 0);
    } catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
      System.out.println("the operation failed");
    }
  }
}

A parent catch blocks its child

The general catch below already covers every exception under it. The compiler refuses the specific catch that follows it.

public class Main {
  public static void main(String[] args) {
    int[] numbers = {1, 2, 3};
    try {
      System.out.println(numbers[5]);
    } catch (Exception e) {
      System.out.println("general failure");
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println("index out of range");
    }
  }
}

Example

public class Main {
  public static void main(String[] args) {
    int[] numbers = {4, 8};
    try {
      System.out.println(numbers[2]);
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println("index out of range");
    }
    try {
      System.out.println(numbers[0] / 0);
    } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
      System.out.println("the operation failed");
    }
    try {
      System.out.println(Integer.parseInt("abc"));
    } catch (NumberFormatException e) {
      System.out.println("not a number");
    }
  }
}

Key points

  • Catch blocks are tested in order, and the first matching type wins.
  • A catch for a specific type can print a message shaped for that failure.
  • The multi-catch form catch (A | B) handles several types in one block.
  • A multi-catch block gives one shared response for every type it lists.
  • A parent type catch placed before a child type catch makes the child unreachable, and the compiler refuses it.

In this example, a specific catch names the index failure, a multi-catch shares one line for the division failure, and a third catch names the parsing failure.

Note

A general catch for Exception belongs after every specific catch for its subtypes.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Two exception types must share one response. Which catch form fits?