Exceptions

Core Java · lesson 13 of 42 · 4 min read

Throw, catch and wrap errors so failures stay visible instead of disappearing.

Open this lesson in the learning hub

Key points

  • Checked exceptions extend Exception. The compiler forces you to catch them or declare throws.
  • Unchecked exceptions extend RuntimeException. They signal bugs — a null reference, a bad index — and are usually not caught.
  • Catch the most specific type first. Multi-catch catch (A | B e) handles two unrelated types in one block.
  • finally always runs. Never return from it, because that discards the exception on its way out.
  • When you rethrow, pass the original as the cause: new RuntimeException(msg, e). That keeps the whole stack trace.
  • Never leave a catch block empty. Handle it, log it, or let it propagate.

Example

public class Main {

    static class OutOfStockException extends Exception {
        OutOfStockException(String message) { super(message); }
    }

    static int reserve(int stock, int wanted) throws OutOfStockException {
        if (wanted > stock) throw new OutOfStockException("wanted " + wanted + ", have " + stock);
        return stock - wanted;
    }

    public static void main(String[] args) {
        try {
            System.out.println("left in stock: " + reserve(10, 3));
            System.out.println("left in stock: " + reserve(2, 5));
        } catch (OutOfStockException e) {
            System.out.println("checked -> " + e.getMessage());
        } finally {
            System.out.println("finally always runs");
        }

        try {
            Object o = "not a number";
            Integer n = (Integer) o;
            System.out.println(n);
        } catch (ClassCastException | NumberFormatException e) {
            System.out.println("multi-catch -> " + e.getClass().getSimpleName());
        }

        try {
            try {
                throw new IllegalStateException("connection reset");
            } catch (IllegalStateException e) {
                throw new RuntimeException("could not load user", e);
            }
        } catch (RuntimeException e) {
            System.out.println(e.getMessage() + " <- caused by: " + e.getCause().getMessage());
        }
    }
}

Handle what you can fix, wrap the rest, and never swallow a cause.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Core Java course, and every lesson in it is listed on the Core Java contents page.