Codectionary / Developer documentation / Java

Exception Handling

Java uses exceptions to signal that something went wrong during execution. Checked exceptions (like IOException) must be either caught or declared with 'throws' in the method signature, enforced by the compiler, while unchecked exceptions (like NullPointerException, extending RuntimeException) do not require this. A try block wraps risky code, one or more catch blocks handle specific exception types, and an optional finally block always runs for cleanup.

Before you start: Methods

Syntax

try {\n  // risky code\n} catch (ExceptionType e) {\n  // handle it\n} finally {\n  // always runs\n}

Breaking down the syntax

try
Groups operations whose failures you want to handle.
catch
Handles a matching exception.
throw
Raises an exception now.
throws IOException
Declares that a method can pass a checked I/O exception to its caller.

How it works

An exception interrupts normal execution. Catch a specific failure when your program can respond, or let a caller handle it.

Start with a small example

Run the first example, then change one value and predict the result.

Apply the idea

Compare the alternatives below before using this pattern in your own project.

Examples

Recover from invalid input

Save as Main.java; compile with javac Main.java and run java Main.

public class Main {
  public static void main(String[] args) {
    try {
      int lessons = Integer.parseInt("three");
      System.out.println(lessons);
    } catch (NumberFormatException error) {
      System.out.println("Please enter a whole number.");
    }
    System.out.println("Ready to try again.");
  }
}
  1. Save as Main.java; compile with javac Main.java and run java Main.
  2. The conversion fails before the first println, then execution continues after the catch.

Validate a method argument

Rejects an invalid value before calculating.

public class Main {
  static int remaining(int completed) {
    if (completed < 0 || completed > 10) {
      throw new IllegalArgumentException("Completed must be between 0 and 10.");
    }
    return 10 - completed;
  }
  public static void main(String[] args) {
    try {
      System.out.println(remaining(12));
    } catch (IllegalArgumentException error) {
      System.out.println(error.getMessage());
    }
  }
}
  1. Rejects an invalid value before calculating.
  2. The caller displays the exception message. Save as Main.java.

Basic try / catch

Catching an exception instead of letting the program crash.

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Error: " + e.getMessage());
}

System.out.println("Program continues running");

Catching Multiple Exception Types

Handling different exceptions differently with multiple catch blocks.

public static void process(String input) {
    try {
        int number = Integer.parseInt(input);
        int result = 100 / number;
        System.out.println(result);
    } catch (NumberFormatException e) {
        System.out.println("Not a valid number: " + input);
    } catch (ArithmeticException e) {
        System.out.println("Cannot divide by zero");
    }
}

process("abc");  // Not a valid number: abc
process("0");     // Cannot divide by zero
process("5");     // 20

finally Block

Code in finally always executes, whether or not an exception was thrown - ideal for cleanup.

public static void readFile() {
    System.out.println("Opening file...");
    try {
        throw new RuntimeException("File not found");
    } catch (RuntimeException e) {
        System.out.println("Error: " + e.getMessage());
    } finally {
        System.out.println("Closing file...");  // always runs
    }
}

readFile();

Custom Exceptions

Defining and throwing your own exception type for domain-specific error handling.

class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

class BankAccount {
    private double balance;

    public BankAccount(double balance) { this.balance = balance; }

    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException("Not enough funds for this withdrawal");
        }
        balance -= amount;
    }
}

BankAccount account = new BankAccount(100);
try {
    account.withdraw(200);
} catch (InsufficientFundsException e) {
    System.out.println("Transaction failed: " + e.getMessage());
}

Best practices

  • Catch specific exception types rather than a broad catch (Exception e), so unrelated bugs are not accidentally silenced
  • Use finally (or try-with-resources) for cleanup code that absolutely must run, like closing files or database connections
  • Create custom exception classes for domain-specific errors, extending Exception (checked) or RuntimeException (unchecked) depending on whether callers should be forced to handle them
  • Don't use exceptions for routine control flow when a simple if check would do - they carry real performance overhead and should signal genuinely exceptional situations

Runtime & versions

Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Java Language Specification

When should I use this?

Recover from invalid input. Distinguish throw from throws. Choose specific handlers.

Common mistakes

Hiding a failure

An empty handler hides that the operation failed.

Incorrect

catch (NumberFormatException error) {}

Corrected

catch (NumberFormatException error) {
  System.out.println("Please enter a whole number.");
}

Compare approaches

  • Checked exceptions: Catch or declare failures such as IOException.
  • Unchecked exceptions: RuntimeException subclasses do not require a throws declaration.
  • Try-with-resources: Close readers and similar resources automatically.

Explore deeper

Cleanup and ordering

Prefer try-with-resources for AutoCloseable objects. finally cannot guarantee execution if the JVM terminates. Put specific handlers before their supertypes.

Specifications & further reading