SyntaxStudy
Sign Up
Java Checked vs Unchecked Exceptions
Java Beginner 1 min read

Checked vs Unchecked Exceptions

Java divides exceptions into two categories: checked and unchecked. Checked exceptions are subclasses of Exception (but not RuntimeException) and represent conditions that a well-written program should anticipate and recover from, such as IOException or SQLException. The compiler enforces that you either catch a checked exception or declare it in the method signature with throws. This makes the error-handling contract explicit in the API. Unchecked exceptions are subclasses of RuntimeException (or Error). They represent programming bugs — NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException — conditions that should be fixed in the code rather than caught at runtime. The compiler does not require you to handle them, which keeps method signatures clean. You can still catch unchecked exceptions when it makes sense, but you are not obligated to. Errors (like OutOfMemoryError or StackOverflowError) are a separate hierarchy representing serious JVM problems that applications generally should not try to catch. A good design principle is to use checked exceptions for recoverable conditions in your public API, unchecked exceptions for programming errors, and to never swallow exceptions silently — always log or rethrow them with meaningful context.
Example
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

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

// Custom unchecked exception
class InvalidAccountException extends RuntimeException {
    InvalidAccountException(String id) {
        super("Account not found: " + id);
    }
}

public class ExceptionTypesDemo {

    static void withdraw(double balance, double amount)
            throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException(amount - balance);
        }
        System.out.println("Withdrew: " + amount);
    }

    static void openAccount(String id) {
        if (id == null || id.isBlank()) {
            throw new InvalidAccountException(id); // unchecked
        }
    }

    public static void main(String[] args) {
        // Checked exception — must handle
        try {
            withdraw(100.0, 150.0);
        } catch (InsufficientFundsException e) {
            System.out.println("Caught: " + e.getMessage());
            System.out.println("Short by: " + e.getAmount());
        }

        // Unchecked exception
        try {
            openAccount("");
        } catch (InvalidAccountException e) {
            System.out.println("Caught unchecked: " + e.getMessage());
        }
    }
}