SyntaxStudy
Sign Up
Java try-catch-finally Blocks
Java Beginner 1 min read

try-catch-finally Blocks

The try block encloses code that might throw an exception. If an exception is thrown, execution immediately jumps to the matching catch block. You can chain multiple catch blocks to handle different exception types; they are evaluated from top to bottom, so more specific exceptions must appear before more general ones. Since Java 7, you can also use a multi-catch (catch (IOException | SQLException e)) to handle multiple types in one block without duplicating code. The finally block always executes after the try/catch, regardless of whether an exception was thrown or caught. This makes it the ideal place to release resources like database connections or file handles that must be closed no matter what happens. However, a return statement inside finally will override any return from the try or catch blocks, which can lead to confusing behaviour and should generally be avoided. Exception chaining is an important technique for preserving the original cause when you catch and rethrow. Instead of throwing a new exception that hides the root cause, use throw new RuntimeException("context message", originalException). The original exception is stored as the cause and will appear in the stack trace, making debugging much easier.
Example
public class TryCatchDemo {

    static int divide(int a, int b) {
        try {
            System.out.println("Attempting division...");
            return a / b;
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
            return -1;
        } finally {
            // Always runs, even if exception not thrown
            System.out.println("finally block executed");
        }
    }

    static void multiCatch(String[] args, int index) {
        try {
            String value = args[index];
            int num = Integer.parseInt(value);
            System.out.println("Parsed: " + num);
        } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
            // Multi-catch: single handler for two types
            System.out.println("Multi-catch: " + e.getClass().getSimpleName()
                               + " - " + e.getMessage());
        }
    }

    static void exceptionChaining() {
        try {
            try {
                throw new java.io.IOException("disk full");
            } catch (java.io.IOException e) {
                // Wrap and rethrow with context
                throw new RuntimeException("Failed to save data", e);
            }
        } catch (RuntimeException e) {
            System.out.println("Top-level: " + e.getMessage());
            System.out.println("Caused by: " + e.getCause().getMessage());
        }
    }

    public static void main(String[] args) {
        System.out.println("Result: " + divide(10, 2));
        System.out.println("Result: " + divide(10, 0));
        multiCatch(new String[]{"42"}, 0);
        multiCatch(new String[]{"abc"}, 0);
        multiCatch(new String[]{}, 5);
        exceptionChaining();
    }
}