CodeGym /Courses /JAVA 25 SELF /Exception hierarchy in Java

Exception hierarchy in Java

JAVA 25 SELF
Level 24 , Lesson 0
Available

1. Class Throwable: the root of all exceptions

Now we will take a close look at how Java’s exception system is structured: what Throwable is, how Exception differs from Error, and what “checked” and “unchecked” exceptions mean. This is the foundation for proper error handling in your programs.

In Java, all exceptions and errors are objects that inherit from the class java.lang.Throwable.
Throwable is the “ancestor” of the entire hierarchy for handling problems in Java.

Schematic:

Throwable
├── Exception
└── Error

Throwable is the base class for everything that can be “thrown” (throw) and “caught” (catch) in Java. You don’t use it directly—it serves as the foundation for more specific error types.

Exception — for “normal” errors

Exception is the base class for all exceptions that can occur in a program and that you can and should handle. These are operational errors: problems with files, networking, I/O, user mistakes, etc. Most of your try-catch blocks will deal with subclasses of Exception.

Examples:

  • IOException — error when working with files or the network.
  • SQLException — error when working with a database.
  • FileNotFoundException — file not found.

Error — for fatal JVM errors

Error is the base class for errors that occur at the Java Virtual Machine (JVM) level. These are usually critical failures that the program cannot and should not handle. If an Error occurs, the application most likely cannot continue running.

Examples:

  • OutOfMemoryError — out of memory.
  • StackOverflowError — stack overflow (for example, due to infinite recursion).
  • NoClassDefFoundError — required class not found.

Important:
Catching and handling Error is almost always a bad idea. These are not your program’s errors but runtime environment failures.

2. Checked vs unchecked exceptions: what does it mean?

In Java, all exceptions fall into two large groups:

Checked exceptions

What are they? Exceptions that the compiler forces you to handle or explicitly rethrow.

When do they occur? They are usually associated with external resources: files, networking, databases, user input.

How to handle? Either wrap the code in try-catch, or add throws to the method signature.

Examples: IOException, SQLException, FileNotFoundException

Example:

public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path); // can throw IOException
    // ...
}

If you neither handle nor rethrow—the program will not compile!

Unchecked exceptions

What are they? Exceptions that the compiler does not require you to handle.

When do they occur? Usually these are program logic errors: division by zero, going out of array bounds, dereferencing null.

How to handle? You can catch them, but you don’t have to. It’s better to prevent such errors with checks.

Where in the hierarchy? They all inherit from RuntimeException.

Examples: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, ArithmeticException

Example:

int[] arr = {1, 2, 3};
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException

The compiler does not force you to catch this exception—but the program will crash on error.

3. The whole hierarchy in one picture

graph TD
    Throwable --> Error
    Throwable --> Exception
    
    Exception --> RuntimeException
    Exception --> CheckedExceptions["(other checked exceptions)"]
    
    Error --> OutOfMemoryError
    Error --> StackOverflowError
    
    RuntimeException --> NullPointerException
    RuntimeException --> IndexOutOfBoundsException
    RuntimeException --> IllegalArgumentException

    %% Styles
    style Throwable fill:#ffa64d,color:#000
    style Exception fill:#ffa64d,color:#000
    style CheckedExceptions fill:#ffa64d,color:#000
    
    style Error fill:#ff4d4d,color:#fff
    style OutOfMemoryError fill:#ff4d4d,color:#fff
    style StackOverflowError fill:#ff4d4d,color:#fff
    
    style RuntimeException fill:#4dff88,color:#000
    style NullPointerException fill:#4dff88,color:#000
    style IndexOutOfBoundsException fill:#4dff88,color:#000
    style IllegalArgumentException fill:#4dff88,color:#000

Table: key differences

Group Parent class Requires handling? Examples
Checked Exception
Exception
Yes
IOException, SQLException
Unchecked
RuntimeException
No
NullPointerException, IndexOutOfBoundsException
Error
Error
No
OutOfMemoryError, StackOverflowError

4. What does it look like in code?

Checked exception: example with files

import java.io.*;

public class FileDemo {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("nofile.txt"); // FileNotFoundException (checked)
            int data = reader.read();
            System.out.println(data);
            reader.close();
        } catch (IOException e) {
            System.out.println("Error working with file: " + e.getMessage());
        }
    }
}

The compiler will make you handle IOException!

Unchecked exception: example with division by zero

public class ExceptionDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int c = a / b; // ArithmeticException (unchecked)
        System.out.println("Result: " + c);
    }
}

The compiler does not require handling, but the program will crash.

5. Why do we need an exception hierarchy?

  • Flexible handling: You can catch both specific errors (FileNotFoundException) and whole groups (IOException or Exception).
  • Code reuse: You can handle errors of one type centrally.
  • Cleaner code: The main logic isn’t cluttered with checks for every little thing.

Example:

try {
    // risky code
} catch (FileNotFoundException e) {
    System.out.println("File not found!");
} catch (IOException e) {
    System.out.println("I/O error!");
} catch (Exception e) {
    System.out.println("Something went wrong: " + e.getMessage());
}

6. Common mistakes when working with exceptions

Mistake #1: Ignoring exceptions. Writing catch (Exception e) {} is bad! You lose information about the cause of the error.

Mistake #2: Catching too much. catch (Exception e) catches everything, even what you didn’t expect. It’s better to catch only the exceptions you know how to handle.

Mistake #3: Catching errors (Error). You should not catch Error unless you are writing low-level code. These are JVM issues, not your program’s.

Mistake #4: Not distinguishing checked and unchecked. Not all exceptions are the same! Checked ones require handling (Exception), unchecked ones do not (RuntimeException and its descendants).

Mistake #5: Not adding information to exceptions. If you create your own exceptions—always add an informative message.

1
Task
JAVA 25 SELF, level 24, lesson 0
Locked
Unraveling Exception Mysteries: Parent Hierarchy
Unraveling Exception Mysteries: Parent Hierarchy
1
Task
JAVA 25 SELF, level 24, lesson 0
Locked
Who's in Charge? The Difference Between Exceptions and Errors
Who's in Charge? The Difference Between Exceptions and Errors
1
Task
JAVA 25 SELF, level 24, lesson 0
Locked
Alerting System: Checked and Unchecked Threats
Alerting System: Checked and Unchecked Threats
1
Task
JAVA 25 SELF, level 24, lesson 0
Locked
Robot Librarian and its "rescue plans"
Robot Librarian and its "rescue plans"
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION