← Back to Home

Multiple catch Blocks

Multiple catch blocks allow a single try block to handle different exception types differently. This enables precise error handling, better diagnostics, and cleaner recovery logic.

This is a very common interview topic, especially around ordering rules and reachability.

Why Multiple catch Blocks Are Needed

  • Different exceptions require different handling
  • Improves clarity and control
  • Avoids catching overly generic exceptions
  • Enhances robustness of applications

Basic Syntax

try {
    // risky code
} catch (ExceptionType1 e1) {
    // handling logic for ExceptionType1
} catch (ExceptionType2 e2) {
    // handling logic for ExceptionType2
}
          
  • ✔ Only one matching catch executes
  • ✔ Remaining catch blocks are skipped

Simple Example

try {
    int[] arr = new int[3];
    int result = 10 / 0;
    System.out.println(arr[5]);
} catch (ArithmeticException e) {
    System.out.println("Arithmetic error");
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index error");
}
          

Output:

Arithmetic error
          

Result: ✔ First exception stops further execution in try

Catch Block Execution Rules (Very Important)

1. Only One catch Executes

  • As soon as an exception occurs
  • JVM jumps to the first matching catch
  • Remaining try statements are skipped

2. Catch Blocks Are Checked Top to Bottom

  • Order matters
  • First matching catch is chosen

Catch Ordering Rule (Interview Favorite)

Child exceptions must be caught before parent exceptions.

❌ Invalid (Unreachable Code)

try {
    int x = 10 / 0;
} catch (Exception e) {
    System.out.println("Exception");
} catch (ArithmeticException e) {
    System.out.println("Arithmetic");
}
          

✔ Compile-time error: ArithmeticException is unreachable

✅ Valid Order

try {
    int x = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Arithmetic");
} catch (Exception e) {
    System.out.println("Exception");
}
          

Multiple Catch with Related Exceptions

try {
    String s = null;
    s.length();
} catch (NullPointerException e) {
    System.out.println("Null reference");
} catch (RuntimeException e) {
    System.out.println("Runtime issue");
}
          
  • ✔ Specific first
  • ✔ General later

Multi-Catch (Java 7+) — Alternative

Handle multiple unrelated exceptions in one catch.

try {
    int a = 10 / 0;
} catch (ArithmeticException | NullPointerException e) {
    System.out.println("Handled");
}
          

Rules:

  • Exceptions must be unrelated
  • Variable e is implicitly final

Multiple Catch vs Multi-Catch

Aspect Multiple Catch Multi-Catch
Handling logic Separate per exception Same logic
Readability High (detailed) Compact
Flexibility More Less
Java version All Java 7+

Multiple Catch Examples (1–20)

1. Basic Multiple catch Blocks

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic exception");
        } catch (Exception e) {
            System.out.println("Generic exception");
        }
    }
}
          

Output:

Arithmetic exception
          

2. Multiple catch with Different Exception Types

class Demo {
    public static void main(String[] args) {
        try {
            String s = null;
            s.length();
        } catch (ArithmeticException e) {
            System.out.println("Math error");
        } catch (NullPointerException e) {
            System.out.println("Null pointer");
        } catch (Exception e) {
            System.out.println("Other error");
        }
    }
}
          

Output:

Null pointer
          

3. Catch Order Matters (Specific → General)

class Demo {
    public static void main(String[] args) {
        try {
            int[] a = new int[2];
            a[5] = 10;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index error");
        } catch (Exception e) {
            System.out.println("General exception");
        }
    }
}
          

Output:

Array index error
          

4. Wrong Catch Order (Compile-Time Error)

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        }
        // catch (Exception e) {}
        // catch (ArithmeticException e) {} // ❌ unreachable code
    }
}
          

Explanation: Parent exception must always be last.

5. Multiple catch for Array and Null Issues

class Demo {
    public static void main(String[] args) {
        try {
            String[] a = new String[2];
            System.out.println(a[1].length());
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array error");
        } catch (NullPointerException e) {
            System.out.println("Null error");
        }
    }
}
          

Output:

Null error
          

6. Using Exception as Last Catch

class Demo {
    public static void main(String[] args) {
        try {
            int a = Integer.parseInt("abc");
        } catch (ArithmeticException e) {
            System.out.println("Math error");
        } catch (NumberFormatException e) {
            System.out.println("Number format error");
        } catch (Exception e) {
            System.out.println("Other error");
        }
    }
}
          

Output:

Number format error
          

7. Multiple catch with File Handling

import java.io.*;

class Demo {
    public static void main(String[] args) {
        try {
            new FileInputStream("test.txt");
        } catch (FileNotFoundException e) {
            System.out.println("File not found");
        } catch (IOException e) {
            System.out.println("IO error");
        }
    }
}
          

Output:

File not found
          

8. Multi-Catch (Java 7+ Alternative)

class Demo {
    public static void main(String[] args) {
        try {
            int[] a = new int[2];
            a[3] = 10;
        } catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
            System.out.println("Array or Null exception");
        }
    }
}
          

Output:

Array or Null exception
          

9. Multiple catch with Inheritance

class Demo {
    public static void main(String[] args) {
        try {
            throw new RuntimeException();
        } catch (RuntimeException e) {
            System.out.println("Runtime exception");
        } catch (Exception e) {
            System.out.println("Exception");
        }
    }
}
          

Output:

Runtime exception
          

10. Same Exception Type Twice (Not Allowed)

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        }
        // catch (ArithmeticException e) {}
        // catch (ArithmeticException e) {} // ❌ duplicate catch
    }
}
          

Explanation: Duplicate catch blocks are not allowed.

11. Multiple catch with finally

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        } catch (NullPointerException e) {
            System.out.println("Null");
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic");
        } finally {
            System.out.println("Finally block");
        }
    }
}
          

Output:

Arithmetic
Finally block
          

12. Nested try with Multiple catch

class Demo {
    public static void main(String[] args) {
        try {
            try {
                int a = 10 / 0;
            } catch (ArithmeticException e) {
                System.out.println("Inner catch");
            }
        } catch (Exception e) {
            System.out.println("Outer catch");
        }
    }
}
          

Output:

Inner catch
          

13. Multiple catch with Method Call

class Demo {
    static void test() {
        int[] a = new int[2];
        a[4] = 10;
    }

    public static void main(String[] args) {
        try {
            test();
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array error");
        } catch (Exception e) {
            System.out.println("General error");
        }
    }
}
          

Output:

Array error
          

14. Catching Checked and Unchecked Together

import java.io.*;

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
            new FileInputStream("a.txt");
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic");
        } catch (FileNotFoundException e) {
            System.out.println("File missing");
        }
    }
}
          

Output:

Arithmetic
          

15. Multiple catch with return

class Demo {
    static int test() {
        try {
            int a = 10 / 0;
            return 1;
        } catch (ArithmeticException e) {
            return 2;
        } catch (Exception e) {
            return 3;
        }
    }

    public static void main(String[] args) {
        System.out.println(test());
    }
}
          

Output:

2
          

16. Multiple catch with Custom Exception

class MyException extends Exception {}

class Demo {
    public static void main(String[] args) {
        try {
            throw new MyException();
        } catch (MyException e) {
            System.out.println("MyException caught");
        } catch (Exception e) {
            System.out.println("Exception caught");
        }
    }
}
          

Output:

MyException caught
          

17. Catching RuntimeException vs Exception

class Demo {
    public static void main(String[] args) {
        try {
            throw new NullPointerException();
        } catch (RuntimeException e) {
            System.out.println("Runtime");
        } catch (Exception e) {
            System.out.println("Exception");
        }
    }
}
          

Output:

Runtime
          

18. Multiple catch with No Exception Occurring

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 2;
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic");
        } catch (Exception e) {
            System.out.println("Exception");
        }
    }
}
          

Output:

(no output)
          

19. Interview Trap – Parent in Middle

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        }
        // catch (Exception e) {}
        // catch (RuntimeException e) {} // ❌ unreachable
    }
}
          

Explanation: Parent (Exception) cannot appear before child (RuntimeException).

20. Interview Summary – Multiple catch Blocks

class Demo {
    public static void main(String[] args) {
        try {
            String s = null;
            s.length();
        } catch (NullPointerException e) {
            System.out.println("Null");
        } catch (Exception e) {
            System.out.println("Exception");
        }
        System.out.println("Program continues");
    }
}
          

Key Points:

  • Order: child → parent
  • Only one catch executes
  • Parent exception must be last
  • Improves precise error handling

Output:

Null
Program continues
          

Best Practices

  • Catch specific exceptions first
  • Avoid catching generic Exception unless necessary
  • Keep handling logic meaningful
  • Log or rethrow when appropriate
  • Avoid empty catch blocks

Common Beginner Mistakes

  • Wrong catch order
  • Catching Exception too early
  • Assuming all catch blocks run
  • Overusing generic catch
  • Ignoring exception details

Interview-Ready Answers

Short Answer

Multiple catch blocks allow handling different exceptions separately for the same try block.

Detailed Answer

In Java, multiple catch blocks can follow a try block to handle different exception types. The JVM selects the first matching catch block based on the exception thrown, and catch blocks must be ordered from most specific to most general to avoid unreachable code.

Key Takeaway

Multiple catch blocks provide precise control over exception handling. Correct ordering and specificity are critical for safe, readable, and maintainable Java code.