Master Core Java Programming From Scratch

Clear, interactive, and structured coding lessons designed for absolute beginners.

Exception Handling in Java

Learn how Java handles runtime errors using try, catch, finally, throw, throws, custom exceptions, and best practices.

What is an Exception?

An exception is an event that interrupts the normal flow of a Java program during execution.

Exception handling allows a program to detect exceptional situations and respond to them without unnecessarily terminating the application.

Java
try
    ↓
Risky Code
    ↓
Exception?
    ↓
catch
    ↓
Handle Exception
    ↓
finally

try-catch

The try block contains code that may throw an exception. The catch block handles the exception.

Java
try {

    int result = 10 / 0;

}
catch (ArithmeticException exception) {

    System.out.println(
        "Cannot divide by zero"
    );

}

finally

The finally block is commonly used for cleanup operations. It normally executes after the try/catch processing, including when an exception occurs.

Java
try {

    System.out.println(
        "Opening resource"
    );

}
catch (Exception exception) {

    System.out.println(
        "Exception occurred"
    );

}
finally {

    System.out.println(
        "Cleanup completed"
    );

}

Multiple catch Blocks

A single try block can be followed by multiple catch blocks when different exception types require different handling.

Java
try {

    int[] numbers = {10, 20, 30};

    System.out.println(
        numbers[5]
    );

}
catch (ArrayIndexOutOfBoundsException exception) {

    System.out.println(
        "Invalid array index"
    );

}
catch (Exception exception) {

    System.out.println(
        "Unexpected error"
    );

}
Put more specific exception types before broader types such as Exception.

Exception Hierarchy

Java
Throwable
├── Error
│   ├── OutOfMemoryError
│   └── StackOverflowError
│
└── Exception
    ├── RuntimeException
    │   ├── NullPointerException
    │   ├── ArithmeticException
    │   └── IllegalArgumentException
    │
    └── Other Checked Exceptions
        ├── IOException
        └── SQLException

Error generally represents serious conditions that applications are not normally expected to recover from, while Exception represents conditions that application code may handle.

Checked Exceptions

Checked exceptions are exceptions that the compiler requires the program to handle or declare.

Java
import java.io.IOException;

void readFile()
    throws IOException {

    // File operations

}

Examples include IOException and many other exceptions derived from Exception but not from RuntimeException.

Unchecked Exceptions

Unchecked exceptions are runtime exceptions. The compiler does not require them to be explicitly caught or declared.

Java
int number = 10;

int result = number / 0;

This produces an ArithmeticException at runtime.

throw Keyword

The throw keyword is used to explicitly throw an exception.

Java
int age = 15;

if (age < 18) {

    throw new IllegalArgumentException(
        "Age must be at least 18"
    );

}

throws Keyword

The throws keyword declares that a method may propagate one or more exceptions to its caller.

Java
import java.io.IOException;

void loadData()
    throws IOException {

    // File operation

}
Remember: throw actually throws an exception, while throws declares possible exceptions.

Custom Exception

Applications can define their own exception classes to represent domain-specific error conditions.

Java
class InvalidAgeException
    extends Exception {

    public InvalidAgeException(
        String message
    ) {

        super(message);

    }

}

Using a Custom Exception

Java
static void validateAge(int age)
    throws InvalidAgeException {

    if (age < 18) {

        throw new InvalidAgeException(
            "Age must be 18 or above"
        );

    }

    System.out.println(
        "Eligible"
    );

}

Multi-Catch

Java allows multiple exception types to be handled by a single catch block using the | operator.

Java
try {

    // risky operation

}
catch (
    IOException | IllegalArgumentException exception
) {

    System.out.println(
        "Operation failed"
    );

}

Try-with-Resources

Try-with-resources automatically closes objects that implement AutoCloseable.

Java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

try (
    BufferedReader reader =
        new BufferedReader(
            new FileReader("data.txt")
        )
) {

    String line = reader.readLine();

    System.out.println(line);

}
catch (IOException exception) {

    System.out.println(
        "Unable to read file"
    );

}
This is generally preferred over manually closing resources in a finally block.

Exception Chaining

Exception chaining preserves the original cause when a higher-level exception is created.

Java
try {

    loadData();

}
catch (IOException exception) {

    throw new RuntimeException(
        "Unable to load application data",
        exception
    );

}

The original exception is retained as the cause and can be inspected using methods such as getCause().

Useful Exception Methods

Method Purpose
getMessage() Returns the exception message.
getCause() Returns the underlying cause.
printStackTrace() Prints diagnostic stack-trace information.
toString() Returns a string representation of the exception.

Stack Trace

A stack trace shows the sequence of method calls that led to the exception.

Java
try {

    int result = 10 / 0;

}
catch (ArithmeticException exception) {

    exception.printStackTrace();

}

Exception Handling Best Practices

  • Catch exceptions at the level where meaningful recovery or handling is possible.
  • Prefer specific exception types instead of catching Exception everywhere.
  • Do not silently ignore exceptions.
  • Use meaningful exception messages.
  • Preserve the original cause when wrapping exceptions.
  • Use try-with-resources for closeable resources.
  • Avoid using exceptions as normal program-flow control.

Common Mistakes

  • Catching a very broad exception without a good reason.
  • Empty catch blocks.
  • Losing the original cause when rethrowing an exception.
  • Using exceptions to replace ordinary conditional logic.

Interview Questions

Exception handling is the mechanism used to detect, propagate, and handle exceptional conditions during program execution.

throw is used to explicitly throw an exception, while throws declares that a method can propagate specified exceptions.

The finally block is commonly used for cleanup code that should execute after exception handling.

A checked exception is one that the compiler requires the application to catch or declare.

Try-with-resources automatically closes resources that implement AutoCloseable.
Summary

Java exception handling uses try, catch, finally, throw, and throws to manage exceptional conditions. Important concepts include checked and unchecked exceptions, custom exceptions, multi-catch, try-with-resources, exception chaining, and good exception-handling practices.