Course topics

By WebNest Studio Engineering Team

Java - Core Tutorial

try, catch, and finally

The try-catch-finally construct is the core syntax Java provides for handling exceptions. Code that might throw an exception is placed inside a try block, the recovery logic goes in one or more catch blocks matched by exception type, and a finally block holds cleanup code that must run no matter what happened.

Why it matters

try, catch and finally are the three parts you use in almost every piece of code that touches files, networks or user input. The order of catch blocks, what finally guarantees, and how try-with-resources closes things for you are details that decide whether a failure is handled cleanly or leaks a connection.

Multiple catch Blocks and Multi-catch

A single try block can be followed by several catch blocks, each handling a different exception type; Java checks them in order and executes the first one whose type matches (or is a superclass of) the thrown exception, so more specific exception types must be listed before more general ones. When two or more exception types should be handled identically, Java lets you combine them into one multi-catch block using a pipe: catch (IOException | SQLException e). This avoids duplicating the same handling code, but the exception types in a multi-catch must not be related by inheritance to each other.

The finally Block

Code inside finally runs after the try block completes, regardless of whether an exception was thrown, whether it was caught, or even whether the try or catch block executed a return statement. This makes finally the correct place for cleanup that absolutely must happen — closing a file, releasing a lock, or closing a database connection — because it runs in almost every circumstance, including when the method is about to return a value.

try-with-resources

Manually closing resources in a finally block is verbose and error-prone. Java's try-with-resources statement automatically closes any resource that implements the AutoCloseable interface once the try block finishes, whether normally or via an exception — you declare the resource inside the parentheses of the try statement itself, and no explicit finally or close() call is needed.

  • try (FileReader fr = new FileReader("data.txt")) { ... } closes fr automatically.
  • Resources are closed in reverse order of declaration if multiple are opened in one try-with-resources.
  • The resource variable is implicitly final and closed even if an exception occurs inside the try block.

Example

Multiple catch blocks with finally, and finally running even with a return

Java
public class TryCatchDemo {
    static int divide(int a, int b) {
        try {
            return a / b;
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
            return -1;
        } finally {
            System.out.println("finally always runs");
        }
    }

    public static void main(String[] args) {
        System.out.println("Result: " + divide(10, 0));
        System.out.println("Result: " + divide(10, 2));
    }
}
Output
Caught: / by zero
finally always runs
Result: -1
finally always runs
Result: 5

Common Mistakes

  • Ordering catch blocks so a general type (like Exception) comes before a more specific one — this makes the specific catch block unreachable and is a compile error.
  • Assuming finally is skipped when a try or catch block returns a value — finally still executes before the method actually returns.
  • Manually closing resources in finally instead of using try-with-resources, which is shorter and closes resources even if the close() call itself would throw.
  • Combining unrelated recovery logic into one catch block using multi-catch when each exception actually needs different handling.

Exercise

Add up the numbers in an array of text values. One value is not a number: skip it, print which one was skipped, and keep going.

Expected output: Skipped x then Sum: 40

Java · starter code
public class SumValid {
    public static void main(String[] args) {
        String[] values = {"10", "x", "30"};
        int sum = 0;

        for (String value : values) {
            // TODO: parse value and add it to sum;
            // if it is not a number, print "Skipped " + value
        }

        System.out.println("Sum: " + sum);
    }
}
Show hints
  • Integer.parseInt throws NumberFormatException for text that is not a number.
  • Put the try-catch inside the loop so one bad value does not stop the rest.
Show solution
Java · solution
public class SumValid {
    public static void main(String[] args) {
        String[] values = {"10", "x", "30"};
        int sum = 0;

        for (String value : values) {
            try {
                sum += Integer.parseInt(value);
            } catch (NumberFormatException e) {
                System.out.println("Skipped " + value);
            }
        }

        System.out.println("Sum: " + sum);
    }
}

Quick quiz

1. A try block executes a return statement. Does its finally block still run?

  • A. Yes, before the method actually returns
  • B. No
  • C. Only if an exception was thrown
  • D. Only for void methods
Show answer

A. finally runs whether the try block finishes normally, returns, or throws.

2. A try has catch (Exception e) followed by catch (ArithmeticException e). What happens?

  • A. It does not compile
  • B. It works; the second is used for arithmetic errors
  • C. Both blocks run
  • D. The first is ignored
Show answer

A. The second catch is unreachable because Exception already catches every ArithmeticException. Subclasses must come before superclasses.

3. What does a method return if its body is try { return 1; } finally { return 2; }?

  • A. 1
  • B. It does not compile
  • C. 2
  • D. 3
Show answer

C. The return in finally replaces the pending return value. This is why returning from finally is considered bad practice.

Interview questions

Is there any case where a finally block does not run?

Show answer

Yes, but only when the JVM itself stops: System.exit() is called inside the try or catch, the JVM crashes, the process is killed, or the thread is a daemon thread and the JVM exits. In every normal case — normal completion, return, or an exception — finally runs.

What is try-with-resources?

Show answer

A form of try that declares resources in parentheses: try (BufferedReader reader = ...) { }. Any resource that implements AutoCloseable is closed automatically when the block ends, whether normally or with an exception, in the reverse of the order they were opened. It replaces the manual close-in-finally pattern and cannot be forgotten.

Key Points to Remember

  • catch blocks are checked in order; more specific exception types must precede more general ones.
  • finally always runs after try/catch, even when a return statement is executed inside them.
  • try-with-resources automatically closes any AutoCloseable resource, removing the need for manual cleanup in finally.
  • Multi-catch (catch (TypeA | TypeB e)) lets one block handle several unrelated exception types identically.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering