Question 7 · Section 7

What is the difference between Error and Exception?

Both classes inherit from Throwable, but they mean fundamentally different problems:

Language versions: English Russian Ukrainian

Junior Level

Key Difference

Both classes inherit from Throwable, but they mean fundamentally different problems:

Error - JVM problems (not application), which usually cannot be fixed.

Exception: AssertionError is technically an Error, but arises from application logic. Used for invariant checking, not external failures.

  • Not under developer control
  • Don’t catch in normal code
  • Examples: OutOfMemoryError, StackOverflowError

Exception - application errors:

  • Expected failures that can be handled
  • Need to be handled
  • Examples: IOException, SQLException

Don’t catch Error in normal code. Exceptions: global thread handler (setDefaultUncaughtExceptionHandler), graceful shutdown, health-check mechanisms.

Visually

Throwable
  ├── Error        <- JVM is broken
  └── Exception    <- Application encountered a problem

Examples

// Error - application is powerless
// java.lang.OutOfMemoryError: Java heap space
List<byte[]> memoryHog = new ArrayList<>();
while (true) memoryHog.add(new byte[1024 * 1024]);

// Exception - can be handled
try {
    Files.readAllLines(Paths.get("missing.txt"));
} catch (IOException e) {
    System.out.println("File not found, using default");
}

Simple rule

  • Error - “JVM died” -> let it crash
  • Exception - “something went wrong” - handle or log

Middle Level

OutOfMemoryError - subtypes

OutOfMemoryError comes in different forms:

  • Java heap space - heap is full
  • Metaspace - no memory for metadata (often when generating classes via CGLIB)
  • Unable to create new native thread - OS denied creating new threads

Even if you catch OOM, the JVM may be in an unstable state.

NoClassDefFoundError vs ClassNotFoundException

This is a classic interview question:

ClassNotFoundException (Exception):

  • You explicitly ask to load a class: Class.forName("com.mysql.Driver")
  • Class is not in classpath
  • Can be handled

NoClassDefFoundError (Error):

  • Class was present at compile time but missing at runtime
  • Or its loading failed due to an error in a static block
  • Critical environment failure

// If in a class’s static block: // static { int x = 1/0; } // On first load: ExceptionInInitializerError // On subsequent attempts: NoClassDefFoundError (class was not initialized)

AssertionError

Inherits from Error. Thrown by the assert operator (with -ea flag):

assert x > 0 : "x must be positive"; // AssertionError if x <= 0

Use assert for checking algorithm invariants, not for API input validation - use IllegalArgumentException for that.

StackOverflowError vs OutOfMemoryError

  • StackOverflowError - stack exhausted (deep recursion). Fix: increase -Xss or fix recursion
  • OutOfMemoryError - heap exhausted (many objects). Fix: increase -Xmx or fix the leak

Senior Level

Handling Error - why it’s bad practice

Even if you caught an Error, the JVM may be in an unstable state. The next operation (even logging) may cause a new Error.

Fail Fast & Die Pattern

In Highload systems, on Error the application should terminate quickly:

public static void main(String[] args) {
    Thread.setDefaultUncaughtExceptionHandler((thread, e) -> {
        if (e instanceof Error) {
            log.error("Fatal error in thread {}", thread.getName(), e);
            System.exit(1); // Die so orchestrator can restart
        }
    });
}

Kubernetes or another orchestrator will restart a fresh instance.

JVM flag for OOM

-XX:OnOutOfMemoryError="kill -9 %p"

Guarantees process death on OutOfMemoryError.

StackOverflowError

Common Error on infinite recursion. Stack size is limited by -Xss. In deep hierarchies or cycles in Hibernate entities, increasing it may be needed.

// Infinite recursion
public int factorial(int n) {
    return n * factorial(n); // StackOverflowError
}

Logging Errors

If you catch Throwable at the top level (main or UncaughtExceptionHandler), do System.exit(1) after logging to not leave the system in a “zombie state”.

Diagnostics

  • javap -v - see method attributes for exception handling understanding
  • Thread Dumps - jstack <pid> shows state of all threads on hang
  • Heap Dumps - jmap helps analyze OutOfMemoryError
  • -XX:+HeapDumpOnOutOfMemoryError - automatic heap dump on OOM

Interview Cheat Sheet

Must know:

  • Error - JVM problems (cannot fix), Exception - application errors (can handle)
  • Error: OutOfMemoryError, StackOverflowError, NoClassDefFoundError - don’t catch
  • Exception is divided into checked and unchecked (RuntimeException)
  • NoClassDefFoundError != ClassNotFoundException: first is Error (was at compile time, missing at runtime), second is Exception (explicitly loaded, not in classpath)
  • AssertionError - technically Error, but from application logic (invariant checking)
  • Fail Fast & Die: on Error - System.exit(1), let orchestrator restart
  • JVM flag -XX:OnOutOfMemoryError="kill -9 %p" guarantees death on OOM
  • Thread.setDefaultUncaughtExceptionHandler - catches Error at top level

Frequent follow-up questions:

  • Can you catch OutOfMemoryError? - Technically yes, but JVM is in unstable state - next operation will fail
  • What is the difference between StackOverflowError and OutOfMemoryError? - StackOverflowError - stack exhausted (recursion), OOM - heap exhausted (many objects)
  • When is AssertionError an Error, not an Exception? - Because assert checks algorithm invariants, not external failures
  • What to do with Error in production? - Log and System.exit(1), Kubernetes will restart the pod

Red flags (NOT to say):

  • “I catch Error and continue working” - JVM is unstable, it’s meaningless
  • “NoClassDefFoundError and ClassNotFoundException are the same” - no, first is Error, second is Exception
  • “AssertionError is used for input validation” - IllegalArgumentException is for that

Related topics:

  • [[What is at the top of the exception hierarchy]]
  • [[What is Throwable]]
  • [[What is an unchecked exception (Runtime Exception)]]
  • [[Is the execution of a finally block guaranteed]]
  • [[What is a stack trace]]