Java Try-Catch-Finally

try-catch-finally is Java’s standard structure for handling code that might throw an exception. The try block runs risky code, catch handles a matching problem, and finally runs cleanup code afterward.

This structure helps your program respond clearly when something goes wrong instead of stopping at the first runtime error.

Basic Syntax

A complete try-catch-finally statement has a try block, one or more catch blocks, and an optional finally block.

public class Main {
    public static void main(String[] args) {
        try {
            int number = Integer.parseInt("42");
            System.out.println("Number: " + number);
        } catch (NumberFormatException e) {
            System.out.println("Invalid number");
        } finally {
            System.out.println("Check complete");
        }
    }
}

Output:

Number: 42
Check complete

The catch block is where you decide what to do about a specific exception. The finally block is optional, but when present it runs whether the try block succeeds or a catch block handles an exception.

Handling An Exception

In this example, Integer.parseInt() throws a NumberFormatException because the text is not a valid integer.

public class Main {
    public static void main(String[] args) {
        String input = "28x";

        try {
            int age = Integer.parseInt(input);
            System.out.println("Age: " + age);
        } catch (NumberFormatException e) {
            System.out.println("Please enter digits only.");
        }

        System.out.println("Done");
    }
}

Output:

Please enter digits only.
Done

When the exception happens, Java skips the rest of the try block and looks for a matching catch. After the catch block finishes, the program continues after the whole try-catch statement.

Using finally

A finally block is useful for code that should run no matter what, such as closing a file, releasing a connection, or printing a final status message. This example uses simple output so the order is easy to see.

public class Main {
    public static void main(String[] args) {
        int[] scores = {90, 84, 77};

        try {
            System.out.println("Score: " + scores[5]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("That score does not exist.");
        } finally {
            System.out.println("Finished reading scores.");
        }
    }
}

Output:

That score does not exist.
Finished reading scores.

The invalid index throws an ArrayIndexOutOfBoundsException. The matching catch handles it, and then finally still runs.

When No Exception Happens

The finally block also runs when the try block succeeds.

public class Main {
    public static void main(String[] args) {
        try {
            int result = 12 / 3;
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Math error");
        } finally {
            System.out.println("Calculation finished.");
        }
    }
}

Output:

Result: 4
Calculation finished.

Because no exception is thrown, the catch block is skipped. The finally block still runs after the successful try block.

Multiple catch Blocks

You can write more than one catch block when different exceptions need different responses. Put more specific exception types before more general ones.

public class Main {
    public static void main(String[] args) {
        String value = "abc";

        try {
            int number = Integer.parseInt(value);
            System.out.println(100 / number);
        } catch (NumberFormatException e) {
            System.out.println("The value is not a number.");
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero.");
        }
    }
}

Output:

The value is not a number.

Only one matching catch block runs for a thrown exception. In this program, parsing fails first, so Java never reaches the division statement.

Good Habits

  • Keep the try block focused on the statements that might fail.
  • Catch specific exception types such as NumberFormatException instead of catching everything.
  • Use finally for cleanup or required follow-up actions.
  • Do not hide errors with empty catch blocks.

Takeaway: use try for risky code, catch for a clear response, and finally for code that must run afterward.