SyntaxStudy
Sign Up
Java Exception Handling with try-catch-finally
Java Beginner 1 min read

Exception Handling with try-catch-finally

Java distinguishes between checked exceptions, which the compiler requires you to handle or declare, and unchecked exceptions (RuntimeException subclasses), which you may handle at your discretion. Common unchecked exceptions include NullPointerException, ArrayIndexOutOfBoundsException, and NumberFormatException. Checked exceptions include IOException and SQLException. The try block encloses code that might throw an exception. One or more catch blocks follow, each specifying an exception type to handle. Multiple exception types can be caught in a single catch using the pipe (|) operator (multi-catch, Java 7+). The finally block, if present, executes regardless of whether an exception was thrown, making it suitable for releasing resources like file handles or database connections. Java 7 introduced the try-with-resources statement, which automatically closes any AutoCloseable resource declared in the try header when the block exits, whether normally or due to an exception. This eliminates the verbose null-check and close-in-finally pattern. Custom exceptions are created by extending Exception (checked) or RuntimeException (unchecked) and optionally adding constructor overloads.
Example
import java.io.StringReader;
import java.io.IOException;

public class ExceptionHandling {

    // Custom checked exception
    static class InsufficientFundsException extends Exception {
        private final double amount;
        InsufficientFundsException(double amount) {
            super("Insufficient funds: need " + amount + " more");
            this.amount = amount;
        }
        double getAmount() { return amount; }
    }

    static double withdraw(double balance, double amount)
            throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException(amount - balance);
        }
        return balance - amount;
    }

    public static void main(String[] args) {

        // Basic try-catch-finally
        try {
            int[] arr = new int[3];
            arr[5] = 10;                    // ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Caught: " + e.getMessage());
        } finally {
            System.out.println("Finally block always runs");
        }

        // Multi-catch
        String[] inputs = {"42", "hello", null};
        for (String input : inputs) {
            try {
                int value = Integer.parseInt(input.trim());
                System.out.println("Parsed: " + value);
            } catch (NumberFormatException | NullPointerException e) {
                System.out.println("Bad input (" + e.getClass().getSimpleName() + ")");
            }
        }

        // Custom checked exception
        try {
            double balance = withdraw(100.0, 150.0);
        } catch (InsufficientFundsException e) {
            System.out.printf("Error: %s (short by %.2f)%n",
                e.getMessage(), e.getAmount());
        }

        // Try-with-resources (auto-close)
        try (StringReader reader = new StringReader("hello")) {
            System.out.println("Read char: " + (char) reader.read());
        } catch (IOException e) {
            e.printStackTrace();
        }
        // reader.close() called automatically
    }
}