Topic 79 of 119 8. Exception Handling in Java Interactive Tutorial

Java Exception Handling: Hierarchy, Philosophy, and Robust Error Handling

9 mins read Last updated: 22 Aug 2026 28,667 views

Direct Answer & Core Concept

Programs do not always run exactly as expected. A file may not exist, a user may enter invalid data, a network connection may fail, or a program may attempt to divide a number by zero.

Java provides exception handling to deal with these unexpected situations in a controlled way. Instead of allowing a program to terminate abruptly, exception handling allows developers to detect problems, respond appropriately, and keep the application in a predictable state.

Java exception handling is built around several important keywords:

Understanding exception handling is essential for writing reliable Java applications.

Detailed Explanation & Mechanics

What Is an Exception in Java?

An exception is an event that occurs during program execution and disrupts the normal flow of instructions.

For example:

This causes an ArithmeticException.

Another example:

Main.java
Run Online
int[] numbers = {
    10, 20, 30
};
System.out.println(numbers[5]);

This causes an ArrayIndexOutOfBoundsException.

Instead of allowing the application to fail without handling the problem, Java provides mechanisms to catch and handle exceptions.


Why Does Exception Handling Matter?

Without exception handling, an unexpected problem can terminate the current operation or thread and produce an error message that may not be useful to the end user.

Consider:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int result = a / b;
        System.out.println(result);
    }
}

The program fails when it reaches the division.

With exception handling:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero.");
        }
    }
}

Output:

The program can respond to the problem in a controlled way.


Exception Handling Philosophy

Good exception handling is not simply about putting every line inside a try-catch block.

The goal is to design software that:

  • detects exceptional situations

  • preserves useful diagnostic information

  • responds appropriately

  • keeps normal code readable

  • prevents unexpected termination where recovery is possible

  • does not silently hide serious problems

A useful principle is:

Handle an exception where you can meaningfully recover from it.

If the current method cannot reasonably recover, it may be better to propagate the exception to a higher level.


Exception Hierarchy in Java

Java exceptions are organized into a class hierarchy.

At the top is:

Main.java
Run Online
Object | Throwable | +------------------+ | |Error Exception | RuntimeException

A simplified hierarchy looks like this:

Architecture Diagram
Throwable
│
├── Error
│
└── Exception
    │
    ├── RuntimeException
    │
    └── Other checked exceptions

Throwable is the root type for objects that can be thrown by Java's exception mechanism.


Throwable

Throwable is the superclass of both:

  • Error

  • Exception

It provides common functionality for exceptional conditions, including methods for obtaining information about the problem and its stack trace.

For example:

Main.java
Run Online
catch (Throwable t) {
    System.out.println(t.getMessage());
}

Catching Throwable broadly is generally not appropriate for ordinary application-level error handling because it also includes serious Error conditions.


Error

Error represents serious problems that applications generally should not attempt to recover from.

Examples include:

Main.java
Run Online
OutOfMemoryErrorStackOverflowErrorNoClassDefFoundError

For example:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        recursiveMethod();
    } static void recursiveMethod() {
        recursiveMethod();
    }
}

This can eventually produce a StackOverflowError.

Important

Error is different from a typical application exception.

You normally should not use exception handling as a general mechanism for recovering from serious JVM or environment failures represented by Error.


Exception

Exception represents conditions that an application may be able to handle.

Examples include:

Main.java
Run Online
IOExceptionSQLExceptionClassNotFoundExceptionRuntimeException

For example:

Main.java
Run Online
try {
    // Code that may cause an exception
} catch (Exception e) {
    // Handle the problem
}

However, catching the generic Exception type should be done carefully. When possible, catch a more specific exception.


RuntimeException

RuntimeException is a subclass of Exception.

Runtime exceptions generally represent programming errors or invalid operations that are detected during execution.

Common examples include:

Main.java
Run Online
ArithmeticExceptionNullPointerExceptionArrayIndexOutOfBoundsExceptionIllegalArgumentExceptionNumberFormatException

Example:

Main.java
Run Online
String value = null;
System.out.println(value.length());

This can cause:


Checked and Unchecked Exceptions

Java exceptions are often divided into two major categories:

Architecture Diagram
Exceptions
│
├── Checked Exceptions
│
└── Unchecked Exceptions
    └── RuntimeException and its subclasses

Understanding this distinction is very important.


Checked Exceptions

Checked exceptions are exceptions that the compiler requires the program to account for.

For example, file operations can involve IOException.

Main.java
Run Online
import java.io.FileReader;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("data.txt");
            reader.close();
        } catch (IOException e) {
            System.out.println("Unable to read the file.");
        }
    }
}

The compiler expects the checked exception to be handled or declared.


Unchecked Exceptions

Unchecked exceptions are exceptions that occur at runtime and are not subject to the same compiler requirement.

They include RuntimeException and its subclasses.

Example:

This produces:

Another example:

Main.java
Run Online
String text = null;
System.out.println(text.length());

This produces:


Checked vs Unchecked Exceptions

FeatureChecked ExceptionUnchecked Exception
Compiler checks handling/declarationYesNo
Common superclassException excluding RuntimeException hierarchyRuntimeException
Often related to external conditionsYesOften programming/validation errors
ExampleIOExceptionNullPointerException
Must catch or declareYesNo

The distinction is important, but it should not be treated as a simple rule that one category is always "good" and the other is always "bad."


The try Block

The try block contains code that may produce an exception.

Main.java
Run Online
try {
    int result = 10 / 0;
}

A try block must be followed by at least one catch block, a finally block, or both.


The catch Block

A catch block handles an exception thrown from the associated try block.

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Division by zero is not allowed.");
}

Output:

Main.java
Run Online
Division by zero is not allowed.

The variable e contains the exception object.


Getting the Exception Message

You can use getMessage():

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println(e.getMessage());
}

The exact message may depend on the Java runtime.


Printing the Exception

You can print the exception object:

Main.java
Run Online
catch (ArithmeticException e) {
    System.out.println(e);
}

This typically includes the exception type and message.


printStackTrace()

For debugging, printStackTrace() can display the stack trace.

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    e.printStackTrace();
}

A stack trace provides information about where the exception occurred and how execution reached that point.

In production applications, logging frameworks are generally preferable to directly printing stack traces to standard output.


The finally Block

The finally block contains code that is intended to run after the try/catch processing.

Example:

Main.java
Run Online
try {
    System.out.println("Inside try");
} catch (Exception e) {
    System.out.println("Inside catch");
} finally {
    System.out.println("Inside finally");
}

Output:

If an exception occurs:

Main.java
Run Online
Inside catchInside finally

The finally block is traditionally used for cleanup.


Why Use finally?

It can be used for cleanup operations such as releasing resources.

For example:

Main.java
Run Online
FileReader reader = null;
try {
    reader = new FileReader("data.txt");
} catch (IOException e) {
    System.out.println("File error");
} finally {
    if (reader != null) {
        try {
            reader.close();
        } catch (IOException e) {
            System.out.println("Could not close file");
        }
    }
}

However, modern Java provides a cleaner approach for many resource-management situations: try-with-resources.


try-with-resources

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

Example:

Main.java
Run Online
import java.io.FileReader;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try(FileReader reader = new FileReader("data.txt")) {
            int data = reader.read();
            System.out.println(data);
        } catch (IOException e) {
            System.out.println("File operation failed.");
        }
    }
}

The resource is automatically closed when the try block finishes.

This is generally preferred over manually managing closable resources with finally.


Multiple catch Blocks

A single try block can have multiple catch blocks.

Main.java
Run Online
try {
    int[] numbers = {
        10, 20, 30
    };
    int result = 10 / 0;
    System.out.println(numbers[5]);
} catch (ArithmeticException e) {
    System.out.println("Arithmetic problem.");
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index problem.");
}

Only the exception that actually occurs is handled.


Order of Multiple catch Blocks

More specific exceptions should come before broader exception types.

Correct:

Main.java
Run Online
try {
    // code
} catch (ArithmeticException e) {
    // specific exception
} catch (Exception e) {
    // broader exception
}

Incorrect:

Main.java
Run Online
try {
    // code
} catch (Exception e) {
    // broad type
} catch (ArithmeticException e) {
    // unreachable
}

The second version produces a compiler error because ArithmeticException is already covered by Exception.


Multi-Catch

Java allows multiple exception types to be handled by one catch block.

Main.java
Run Online
try {
    // code
} catch (ArithmeticException | NumberFormatException e) {
    System.out.println("Invalid numeric operation.");
}

This can reduce duplicated handling code when the response is the same.


Nested try Blocks

A try block can be placed inside another try block.

Main.java
Run Online
try {
    System.out.println("Outer try");
    try {
        int result = 10 / 0;
    } catch (ArithmeticException e) {
        System.out.println("Inner catch");
    }
} catch (Exception e) {
    System.out.println("Outer catch");
}

Nested exception handling should be used only when it makes the control flow clearer.

Deeply nested exception handling can make code difficult to understand.


throw Keyword

The throw keyword is used to explicitly throw an exception.

Example:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        int age = 15;
        if (age < 18) {
            throw new IllegalArgumentException("Age must be 18 or above.");
        } System.out.println("Allowed");
    }
}

The program explicitly creates and throws an exception.


throw with a Custom Message

Main.java
Run Online
throw new IllegalArgumentException("Invalid age");

The message helps explain why the operation failed.


throw with Custom Exception

You can also create your own exception class.

Main.java
Run Online
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

Then:

Main.java
Run Online
public class Main {
    static void checkAge(int age) throws InvalidAgeException {
        if (age < 18) {
            throw new InvalidAgeException("Age must be at least 18.");
        } System.out.println("Age is valid.");
    } public static void main(String[] args) {
        try {
            checkAge(15);
        } catch (InvalidAgeException e) {
            System.out.println(e.getMessage());
        }
    }
}

Output:


throws Keyword

The throws keyword is used in a method declaration to indicate exceptions that the method may propagate to its caller.

Example:

Main.java
Run Online
import java.io.IOException;
public class Main {
    static void readFile() throws IOException {
        // File operation
    }
}

The method does not handle the exception itself. Instead, it declares that callers need to account for it.


throw vs throws

These two keywords are often confused.

throwthrows
Used to explicitly throw an exceptionUsed to declare exceptions
Appears inside method/codeAppears in method declaration
Throws one exception object at a timeCan declare multiple exception types
Example: throw new Exception()Example: throws IOException

Example:

Main.java
Run Online
throw new IllegalArgumentException("Invalid value");

Declaration:

Main.java
Run Online
void readFile() throws IOException {
}

Exception Propagation

If a method does not handle an exception, it can propagate to its caller.

Example:

Main.java
Run Online
public class Main {
    static void method3() {
        int result = 10 / 0;
    } static void method2() {
        method3();
    } static void method1() {
        method2();
    } public static void main(String[] args) {
        try {
            method1();
        } catch (ArithmeticException e) {
            System.out.println("Exception handled in main.");
        }
    }
}

The exception travels through the call stack until a suitable handler is found.

The simplified flow is:

Main.java
Run Online
method1()↓method2()↓method3()↓Exception↓method2() does not handle↓method1() does not handle↓main() handles

Exception Stack Trace

When an exception occurs, Java creates a stack trace that shows the sequence of method calls involved.

Example:

Main.java
Run Online
public class Main {
    static void calculate() {
        int result = 10 / 0;
    } public static void main(String[] args) {
        calculate();
    }
}

The stack trace can show information such as:

Main.java
Run Online
ArithmeticException at Main.calculate(...) at Main.main(...)

The exact formatting depends on the Java runtime.


Exception Chaining

Sometimes one exception occurs because another underlying exception caused the operation to fail.

Java supports exception chaining so the original cause can be preserved.

Example:

Main.java
Run Online
try {
    // Some operation
} catch (Exception e) {
    throw new RuntimeException("Operation failed", e);
}

Here:

  • "Operation failed" provides higher-level context.

  • e preserves the original cause.

This is useful when translating low-level exceptions into application-specific exceptions.


getCause()

You can retrieve the original cause using:

Main.java
Run Online
Throwable cause = e.getCause();

Example:

Main.java
Run Online
try {
    // operation
} catch (Exception e) {
    System.out.println("Cause: " + e.getCause());
}

Preserving the original cause is important for debugging.


Custom Exceptions

Applications often define custom exception classes to represent domain-specific problems.

Example:

Main.java
Run Online
class InvalidAmountException extends Exception {
    public InvalidAmountException(String message) {
        super(message);
    }
}

Using it:

Main.java
Run Online
public class Main {
    static void withdraw(double amount) throws InvalidAmountException {
        if (amount <= 0) {
            throw new InvalidAmountException( "Amount must be greater than zero.");
        } System.out.println("Withdrawal accepted.");
    } public static void main(String[] args) {
        try {
            withdraw(-500);
        } catch (InvalidAmountException e) {
            System.out.println(e.getMessage());
        }
    }
}

Output:

Main.java
Run Online
Amount must be greater than zero.

Checked Custom Exception

A custom exception that extends Exception is generally a checked exception.

Main.java
Run Online
class InvalidUserException extends Exception {
    public InvalidUserException(String message) {
        super(message);
    }
}

Methods that throw it generally need to catch it or declare it.


Unchecked Custom Exception

A custom exception can extend RuntimeException.

Main.java
Run Online
class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String message) {
        super(message);
    }
}

Now callers are not required by the compiler to catch or declare it.


When Should You Create a Custom Exception?

Custom exceptions are useful when the application has a meaningful domain-specific failure.

Examples:

Main.java
Run Online
InvalidAccountExceptionInsufficientBalanceExceptionInvalidOrderExceptionUserNotFoundExceptionPaymentFailedException

The exception name should communicate the problem clearly.

Do not create custom exception classes merely to make the code look more sophisticated.


Exception Handling and Input Validation

Exception handling can work together with input validation.

For example:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        String input = "abc";
        try {
            int number = Integer.parseInt(input);
            System.out.println(number);
        } catch (NumberFormatException e) {
            System.out.println("Please enter a valid number.");
        }
    }
}

Output:

Main.java
Run Online
Please enter a valid number.

NumberFormatException

NumberFormatException occurs when a string cannot be converted to the expected numeric format.

Example:

Main.java
Run Online
String value = "abc";
int number = Integer.parseInt(value);

This causes:

Handle it when invalid input is an expected possibility.


NullPointerException

A NullPointerException occurs when code attempts an operation on a null reference where an object is required.

Example:

Main.java
Run Online
String name = null;
System.out.println(name.length());

This causes a NullPointerException.

Instead of simply catching it everywhere, the better solution is often to understand why the reference became null and fix the underlying logic.


ArrayIndexOutOfBoundsException

This occurs when an array is accessed outside its valid index range.

Main.java
Run Online
int[] numbers = {
    10, 20, 30
};
System.out.println(numbers[5]);

The valid indexes are:

Index 5 is invalid.


ArithmeticException

This exception commonly occurs during invalid arithmetic operations such as integer division by zero.

The result is an ArithmeticException.


IllegalArgumentException

This exception indicates that a method received an inappropriate argument.

Example:

Main.java
Run Online
public static void setAge(int age) {
    if (age < 0) {
        throw new IllegalArgumentException( "Age cannot be negative.");
    }
}

This is useful for validating method arguments.


IllegalStateException

IllegalStateException can indicate that an object or operation is not in an appropriate state for the requested operation.

Example:

Main.java
Run Online
throw new IllegalStateException( "Operation is not allowed in the current state.");

This is useful when the problem is the object's current state rather than the argument itself.


Exception Handling Best Practices

1. Catch Specific Exceptions

Prefer:

Main.java
Run Online
catch (NumberFormatException e) {
}

instead of immediately using:

Specific exceptions make the code clearer and allow more appropriate recovery.


2. Do Not Swallow Exceptions

Avoid:

Main.java
Run Online
try {
    // code
} catch (Exception e) {
}

This silently discards the error and makes debugging much harder.

If you catch an exception, either handle it meaningfully, log it appropriately, or propagate it.


3. Preserve the Original Cause

When wrapping an exception:

Main.java
Run Online
throw new RuntimeException("Database operation failed", e);

Keep the original exception as the cause.

This preserves valuable diagnostic information.


4. Do Not Use Exceptions for Normal Control Flow

Avoid using exceptions for ordinary decisions.

Bad design:

Main.java
Run Online
try {
    int value = Integer.parseInt(input);
} catch (NumberFormatException e) {
    // normal expected branching
}

Depending on the application, validation may be better performed before conversion when practical.

Exceptions are primarily for exceptional conditions, not every normal branch of logic.


5. Keep try Blocks Focused

Instead of putting a huge amount of unrelated code into one try block, keep the protected operation reasonably focused.

This makes it easier to understand which operation can fail.


6. Use try-with-resources for Resources

For resources such as streams, readers, and other AutoCloseable objects:

Main.java
Run Online
try(FileReader reader = new FileReader("data.txt")) {
    // use resource
}

This is generally cleaner and safer than manually closing resources.


7. Log Exceptions Properly

In production applications, use an appropriate logging framework rather than relying on:

Logging can provide useful context such as:

  • timestamp

  • log level

  • request information

  • exception type

  • stack trace

  • application context


Common Exception Handling Mistakes

Mistake 1: Catching Everything

This is usually far too broad for normal application logic.


Mistake 2: Empty Catch Block

This hides problems.


Mistake 3: Losing the Original Cause

Avoid:

Main.java
Run Online
catch (Exception e) {
    throw new RuntimeException("Something failed");
}

Prefer:

Main.java
Run Online
catch (Exception e) {
    throw new RuntimeException("Something failed", e);
}

Mistake 4: Logging and Throwing Without Purpose

Be careful not to repeatedly log the same exception at every layer.

A useful approach is to add context where appropriate and ensure the exception is logged at a suitable boundary.


Mistake 5: Catching an Exception You Cannot Handle

If the current method cannot meaningfully recover, propagating the exception may be better than catching it and pretending the problem was resolved.


Exception Handling Flow

The general execution flow is:

Main.java
Run Online
try |↓Code executes | Exception? / \ No Yes | |↓↓Continue catch |↓Handle/Propagate |↓finally

The exact control flow depends on whether an exception occurs and whether it is handled.


Complete Exception Handling Example

Main.java
Run Online
import java.util.Scanner;
public class ExceptionExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
            System.out.print("Enter first number: ");
            int a = scanner.nextInt();
            System.out.print("Enter second number: ");
            int b = scanner.nextInt();
            int result = a / b;
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println( "Cannot divide by zero.");
        } catch (Exception e) {
            System.out.println( "Invalid input.");
        } finally {
            scanner.close();
            System.out.println( "Program finished.");
        }
    }
}

This example demonstrates:

  • try

  • multiple catch blocks

  • specific exception handling

  • generic fallback handling

  • finally

  • resource cleanup


Exception Handling Architecture

A useful mental model is:

Architecture Diagram
Application
    |
↓
Operation
    |
↓
Exceptional condition
    |
↓
Exception object
    |
↓
Nearest suitable handler
    |
    ├── Recover
    ├── Add context
    ├── Log
    └── Propagate

Good exception handling is about choosing the correct action for the situation.


Robust Error Handling

Robust software does not mean that every possible error is hidden.

Instead, robust error handling means the application:

  • detects failures

  • preserves useful information

  • responds appropriately

  • cleans up resources

  • avoids corrupting application state

  • gives users useful feedback

  • provides developers with diagnostic information

For example, instead of displaying:

to a normal user, an application might display:

Main.java
Run Online
We could not complete your request. Please try again.

while recording the technical details in an appropriate log.


Exception Handling Layers

Large applications often handle exceptions at different layers.

Low-Level Layer

A database or file layer may detect a technical problem.

Service Layer

The service layer can add business context.

Application Layer

The outer layer can convert the problem into a suitable response.

Main.java
Run Online
Request could not be completed.

This creates a separation between technical details and user-facing messages.


Exception Handling Design Principle

A good design often follows this pattern:

Main.java
Run Online
Detect↓Understand↓Add useful context↓Recover or propagate↓Log at the appropriate boundary↓Give an appropriate response

The exact approach depends on the application's architecture.


Frequently Asked Questions

What is exception handling in Java?

Exception handling is Java's mechanism for detecting and responding to exceptional conditions without allowing the normal application flow to fail unexpectedly.

What are the main exception handling keywords?

The main keywords are:

Main.java
Run Online
trycatchfinallythrowthrows

What is the difference between Error and Exception?

Error generally represents serious JVM or system-level problems, while Exception represents conditions applications may often handle or propagate.

What is a checked exception?

A checked exception is an exception that the compiler requires the program to catch or declare, such as many IOException cases.

What is an unchecked exception?

Unchecked exceptions are RuntimeException and its subclasses. The compiler does not require them to be caught or declared.

What is try-catch?

try contains code that may throw an exception, while catch provides code for handling a matching exception.

What is finally?

finally is used for code that should generally execute after try/catch processing, commonly for cleanup.

What is throw?

throw explicitly throws an exception object.

Example:

Main.java
Run Online
throw new IllegalArgumentException("Invalid value");

What is throws?

throws declares exceptions that a method may propagate.

Example:

Main.java
Run Online
void readFile() throws IOException {
}

Can one try block have multiple catch blocks?

Yes.

Main.java
Run Online
try {
    // code
} catch (ArithmeticException e) {
    // handling
} catch (NumberFormatException e) {
    // handling
}

Can we have try without catch?

Yes, a try block can be followed by finally without a catch.

Main.java
Run Online
try {
    // code
} finally {
    // cleanup
}

Should I catch Exception everywhere?

No. Catch exceptions where you can handle them meaningfully, and prefer specific exception types.

What is exception propagation?

Exception propagation occurs when a method does not handle an exception and it moves up the call stack toward its caller.

What is a custom exception?

A custom exception is a user-defined exception class created for an application's specific domain or business conditions.

Graphic and Design Ideas

Graphic 1: Java Exception Hierarchy

Create a clear hierarchy diagram:

Architecture Diagram
                 Throwable
                    │
          ┌─────────┴─────────┐
          │                   │
        Error              Exception
                              │
                    ┌─────────┴─────────┐
                    │                   │
          RuntimeException       Checked Exceptions
                    │
          ┌─────────┼──────────┐
          │         │          │
       NullPointer  Arithmetic  IllegalArgument
       Exception    Exception   Exception

Graphic 2: Exception Handling Flow

Architecture Diagram
             try
              │
↓
Execute Code
              │
        ┌─────┴─────┐
        │           │
    No Error      Error
        │           │
↓

↓
Continue      catch
                    │
↓
Handle / Propagate
                    │
↓
finally

Graphic 3: throw vs throws

Main.java
Run Online
throw↓Actually throws an exception↓throw new Exception();
throws↓Declares possible exceptions↓method() throws IOException

Graphic 4: Checked vs Unchecked

Architecture Diagram
              Exception
                  │
        ┌─────────┴─────────┐
        │                   │
     Checked            RuntimeException
        │                   │
   Compiler checks       Unchecked
   catch/declare         by compiler

Graphic 5: Robust Error Handling

Main.java
Run Online
Detect↓Understand↓Handle↓Recover OR Propagate↓Preserve Cause↓Log Appropriately↓Useful User Response

This graphic can be used near the "Robust Error Handling" section.


Final Summary

Java exception handling provides a structured way to deal with unexpected conditions during program execution.

The most important concepts are:

Main.java
Run Online
try↓Potentially failing codecatch↓Handle matching exceptionfinally↓Cleanupthrow↓Explicitly create/throw an exceptionthrows↓Declare possible propagation

The exception hierarchy begins with Throwable and branches into Error and Exception. Understanding this hierarchy helps developers choose appropriate exception types and handlers.

Runnable Code Example: Java Exception Handling

Java 17+
Main.java
Run Online
public class ExceptionHierarchyDemo {
    public static void main(String[] args) {
        try {
            int division = 10 / 0;
        } catch (ArithmeticException e) {
            System.err.println("Caught ArithmeticException: " + e.getMessage());
            System.out.println("Recovered gracefully!");
        }
    }
}

Common Java Technical Interview Questions & Answers

Interview Prep
Q1

What is the difference between Error and Exception in Java?

Errors (e.g. OutOfMemoryError) represent serious JVM system failures that applications should not attempt to catch; Exceptions represent conditions that reasonable programs can handle.
Q2

What is the root class of all exceptions and errors in Java?

java.lang.Throwable.

Key Takeaways, Best Practices & Clean Code Rules

Java Best Practice & Production Rules

Never catch Throwable or Error in business code; catch specific Exception subtypes to prevent masking JVM fatal faults.