00:00

Exception Handling in Java – Complete Guide with Examples

An exception is an unexpected event that interrupts the normal flow of a program: dividing by zero, opening a file that does not exist, reading text where a number was expected, or losing a network connection. Exception handling is how Java lets you detect these problems, respond to them, and keep the program running or fail gracefully.

This guide introduces the whole topic: what happens when an exception is not handled, the exception class hierarchy, the five keywords (try, catch, finally, throw, throws), how exceptions travel up the call stack, and the best practices professionals follow. Each part links to a detailed tutorial.

1. What Happens Without Exception Handling

When an exception is thrown and nothing catches it, the JVM stops the thread and prints the exception and a stack trace:

WithoutHandling.java
public class WithoutHandling {
    public static void main(String[] args) {
        System.out.println("Calculating average...");
        int total = 250, count = 0;
        int average = total / count;            // ArithmeticException: nobody handles it
        System.out.println("Average: " + average);   // never runs
    }
}
Output
Calculating average...
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at WithoutHandling.main(WithoutHandling.java:5)

The last println never ran. The stack trace tells you exactly what went wrong (ArithmeticException: / by zero) and where (WithoutHandling.java, line 5). Reading stack traces is one of the most useful debugging skills in Java.

2. Handling the Exception with try-catch

Put risky code in a try block and the recovery code in a catch block. A finally block runs whether or not an exception occurred:

WithHandling.java
public class WithHandling {
    public static void main(String[] args) {
        System.out.println("Calculating average...");
        int total = 250, count = 0;
        try {
            int average = total / count;
            System.out.println("Average: " + average);
        } catch (ArithmeticException e) {
            System.out.println("Cannot calculate: no items (" + e.getMessage() + ")");
        } finally {
            System.out.println("Calculation finished");
        }
        System.out.println("The program continues normally.");
    }
}
Output
Calculating average...
Cannot calculate: no items (/ by zero)
Calculation finished
The program continues normally.

This time the program reported a clear message and carried on. See try-catch block and finally block.

3. The Exception Hierarchy

Java exception class hierarchy
Simplified hierarchy
Throwable
 ├─ Error                       serious JVM problems: OutOfMemoryError, StackOverflowError
 └─ Exception                   problems a program can handle
     ├─ IOException, SQLException, ...           checked exceptions
     └─ RuntimeException                          unchecked exceptions
         ├─ NullPointerException
         ├─ ArithmeticException
         ├─ IllegalArgumentException → NumberFormatException
         └─ IndexOutOfBoundsException → ArrayIndexOutOfBoundsException
  • Errors signal problems you usually cannot recover from. See Error vs Exception.
  • Checked exceptions must be caught or declared; the compiler enforces it.
  • Unchecked exceptions (RuntimeException and its subclasses) usually signal programming bugs and need not be declared. See Checked vs Unchecked.

4. The Five Exception Keywords

KeywordPurposeTutorial
tryWraps code that might throw an exceptiontry-catch
catchHandles a specific type of exceptionmultiple catch
finallyRuns clean-up code in every casefinally
throwThrows an exception objectthrow
throwsDeclares exceptions a method may throwthrows

Related features: try-with-resources closes files and connections automatically, nested try blocks handle errors at several levels, and custom exceptions describe problems specific to your application.

5. How Exceptions Propagate

If a method does not catch an exception, it ends immediately and the exception passes to its caller, then to that caller's caller, and so on up the call stack, until some method catches it or it reaches the top and stops the thread:

Propagation.java
public class Propagation {
    static int parseAge(String text) {
        return Integer.parseInt(text);          // may throw NumberFormatException
    }

    static String register(String name, String ageText) {
        int age = parseAge(ageText);            // not caught here: passes upward
        return name + " registered, age " + age;
    }

    public static void main(String[] args) {
        String[][] inputs = {{"Asha", "28"}, {"Ravi", "twenty"}};
        for (String[] in : inputs) {
            try {
                System.out.println(register(in[0], in[1]));
            } catch (NumberFormatException e) {   // caught two levels up
                System.out.println("Could not register " + in[0] + ": " + e.getMessage());
            }
        }
    }
}
Output
Asha registered, age 28
Could not register Ravi: For input string: "twenty"

Neither parseAge() nor register() handles the error; main() catches it where it can decide what to do. Catching exceptions at the level that knows how to respond is a key design principle.

6. Getting Information from an Exception

ExceptionInfo.java
public class ExceptionInfo {
    static void loadUser(String id) {
        if (id.isBlank()) throw new IllegalArgumentException("user id must not be blank");
    }

    public static void main(String[] args) {
        try {
            loadUser(" ");
        } catch (IllegalArgumentException e) {
            System.out.println("getMessage():   " + e.getMessage());
            System.out.println("toString():     " + e);
            System.out.println("class name:     " + e.getClass().getName());
            System.out.println("thrown in:      " + e.getStackTrace()[0].getMethodName() + "()");
            System.out.println("stack trace:");
            e.printStackTrace(System.out);
        }
    }
}
Output
getMessage():   user id must not be blank
toString():     java.lang.IllegalArgumentException: user id must not be blank
class name:     java.lang.IllegalArgumentException
thrown in:      loadUser()
stack trace:
java.lang.IllegalArgumentException: user id must not be blank
	at ExceptionInfo.loadUser(ExceptionInfo.java:3)
	at ExceptionInfo.main(ExceptionInfo.java:8)

Every exception carries a message, its type and the stack trace of where it was created. Exceptions can also wrap a cause (getCause()), the original exception that led to this one.

7. Common Built-in Exceptions

ExceptionTypical cause
NullPointerExceptionCalling a method on a null reference
ArithmeticExceptionInteger division by zero
ArrayIndexOutOfBoundsExceptionInvalid array index
NumberFormatExceptionParsing text that is not a number
ClassCastExceptionCasting an object to an incompatible type
IllegalArgumentExceptionInvalid method argument
IllegalStateExceptionMethod called at the wrong time
IOException / FileNotFoundExceptionFile or stream problems (checked)
InterruptedExceptionA waiting thread was interrupted (checked)

More in Types of Exception in Java.

8. Best Practices

  • Catch specific exceptions, not Exception or Throwable, unless you are at the top level of an application.
  • Never swallow exceptions with an empty catch; at least log them.
  • Fail fast: validate inputs and throw clear exceptions early.
  • Use try-with-resources for anything that must be closed.
  • Keep the cause when wrapping: throw new ServiceException("Order failed", e);.
  • Do not use exceptions for normal control flow; they are for exceptional situations.
  • Prefer avoiding exceptions where a simple check works, for example testing for null or using Optional.

9. Summary

  • An exception is an event that disrupts normal execution; unhandled, it stops the thread with a stack trace.
  • All exceptions descend from Throwable, split into Error and Exception; RuntimeException subclasses are unchecked.
  • try, catch, finally, throw and throws are the core tools.
  • Uncaught exceptions propagate up the call stack until handled.
  • Handle exceptions where you can respond meaningfully, and never hide them.

Reference: dev.java: Exceptions