00:00

Error vs Exception in Java – Key Differences Explained

In Java, everything that can be thrown is a Throwable, and Throwable has two branches: Error and Exception. They look similar in code, but they mean very different things. An Exception is a problem your program can expect and often recover from. An Error is a serious problem in the JVM or its environment that your program usually cannot fix.

This tutorial explains the difference with examples, lists the most common errors, and shows what you should and should not catch.

1. Where They Sit in the Hierarchy

Throwable hierarchy with Error and Exception branches
ErrorVsException.java
public class ErrorVsException {
    static void describe(Throwable t) {
        String kind = (t instanceof Error) ? "Error" : (t instanceof RuntimeException) ? "unchecked Exception" : "checked Exception";
        System.out.printf("%-32s -> %s%n", t.getClass().getSimpleName(), kind);
    }

    public static void main(String[] args) {
        describe(new OutOfMemoryError());
        describe(new StackOverflowError());
        describe(new NoClassDefFoundError());
        describe(new java.io.IOException());
        describe(new InterruptedException());
        describe(new NullPointerException());
        describe(new IllegalArgumentException());
    }
}
Output
OutOfMemoryError                 -> Error
StackOverflowError               -> Error
NoClassDefFoundError             -> Error
IOException                      -> checked Exception
InterruptedException             -> checked Exception
NullPointerException             -> unchecked Exception
IllegalArgumentException         -> unchecked Exception

All errors are unchecked. Exceptions are checked unless they extend RuntimeException.

2. Error vs Exception: Comparison

AspectErrorException
Package / parentjava.lang.Error, extends Throwablejava.lang.Exception, extends Throwable
MeaningSerious problem in the JVM or environmentProblem in the application or its inputs
Recoverable?Usually notOften yes
Checked?Always uncheckedChecked, except RuntimeException subclasses
Should you catch it?Generally noYes, where you can handle it
Caused byLack of memory, deep recursion, missing classes, JVM failuresBad input, missing files, network issues, programming bugs
ExamplesOutOfMemoryError, StackOverflowError, NoClassDefFoundErrorIOException, SQLException, NullPointerException

3. Exceptions: Recover and Continue

Exceptions describe problems that the program can anticipate. Handling them lets the program carry on:

RecoverableException.java
public class RecoverableException {
    public static void main(String[] args) {
        // An Exception: the program can recover and continue
        String[] inputs = {"42", "forty-two", "7"};
        int total = 0;
        for (String in : inputs) {
            try {
                total += Integer.parseInt(in);
            } catch (NumberFormatException e) {
                System.out.println("skipping invalid input: " + in);
            }
        }
        System.out.println("total = " + total);
    }
}
Output
skipping invalid input: forty-two
total = 49

4. Errors: Something Is Seriously Wrong

Errors are thrown by the JVM when it cannot continue normally. This demo catches two of them only to show what they look like; in real code you would fix the cause (add a base case to the recursion, process data in smaller pieces) instead of catching the error:

ErrorDemo.java
public class ErrorDemo {
    static int depth = 0;
    static void dive() { depth++; dive(); }      // no base case

    public static void main(String[] args) {
        // An Error: caught here only to demonstrate it; real code should fix the cause instead
        try {
            dive();
        } catch (StackOverflowError e) {
            System.out.println("StackOverflowError: the call stack ran out after many nested calls");
        }
        try {
            int[] huge = new int[Integer.MAX_VALUE];
            System.out.println(huge.length);
        } catch (OutOfMemoryError e) {
            System.out.println("OutOfMemoryError: " + e.getMessage());
        }
    }
}
Output
StackOverflowError: the call stack ran out after many nested calls
OutOfMemoryError: Requested array size exceeds VM limit

5. Common Errors

ErrorTypical causeWhat to do
OutOfMemoryErrorHeap full, memory leak, huge allocationsFix leaks, process data in chunks, increase -Xmx
StackOverflowErrorUnbounded recursionAdd a base case or use iteration
NoClassDefFoundErrorClass present at compile time but missing at runtimeFix the class path or dependencies
ExceptionInInitializerErrorException in a static initializerFix the static initialisation code
UnsatisfiedLinkErrorNative library not foundInstall the library or fix java.library.path
AssertionErrorFailed assert or "impossible" stateFix the bug the assertion detected

6. What Should You Catch?

  • Catch specific exceptions you can handle where they occur.
  • Do not catch Error in normal code. After an OutOfMemoryError the program may be in an unpredictable state.
  • Avoid catch (Throwable t); it also catches errors. At the very top of an application (for example a thread's run loop), it may be used to log a crash before exiting.
  • catch (Exception e) does not catch errors, which is one reason it is preferred over Throwable for catch-all logging.

7. Summary

  • Error and Exception are the two subclasses of Throwable.
  • Errors signal serious JVM or environment problems and are always unchecked; applications usually should not catch them.
  • Exceptions signal application-level problems; checked exceptions must be handled, runtime exceptions usually reveal bugs.
  • Prevent errors by fixing their causes, and handle exceptions where you can respond meaningfully.

Related Tutorials