Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 19

Checked vs. Unchecked Exceptions

Recommended resources

In our last session, we established a solid foundation for handling errors in Java using try-catch-finally and the modern try-with-resources statement. You now have the tools to make your code resilient to unexpected situations. Today, we delve deeper to answer a crucial question that shapes Java's entire approach to error handling: when is handling an error mandatory, and when is it optional?

This lesson will focus on differentiating between Java's two categories of exceptions: checked and unchecked. Understanding this distinction is not just academic; it reflects a core design philosophy of the language aimed at creating robust applications. It is also a frequent topic in technical interviews, as it reveals your understanding of how to write reliable, professional code. We will explore what defines each type, how the Java compiler treats them differently, and the logic behind their use cases.

1. The Fundamental Difference: Compile-Time vs. Runtime Enforcement

In the previous lesson, you learned to wrap "risky" code in a try-catch block. But have you noticed that sometimes the Java compiler forces you to do this, while other times it doesn't? For example, trying to read a file that might not exist causes a compile error if not handled, but trying to access a method on a null object compiles fine, only to crash at runtime. This is the central difference between checked and unchecked exceptions.

  • Checked Exceptions: These are exceptions that the Java compiler checks at compile-time. If a method can throw a checked exception, it must either handle it with a try-catch block or declare that it can throw the exception using the throws keyword in the method signature. These typically represent errors that are external to the program and potentially recoverable, like a missing file or a failed network connection.

  • Unchecked Exceptions: These are exceptions that the compiler does not check. Your code will compile even if a method can throw an unchecked exception without handling or declaring it. These almost always represent programming errors or bugs, such as logical flaws that lead to a NullPointerException or ArrayIndexOutOfBoundsException.

The "Coding with John" channel provides an excellent, clear explanation with practical coding examples that illustrate this difference.

Checked vs. Unchecked Exceptions in Java Tutorial - What's The Difference?

This video walks through the distinction using FileNotFoundException as a prime example of a checked exception and NullPointerException for an unchecked exception. It clearly demonstrates the different behaviors of the compiler in each case.

First, watch the segment on checked exceptions, from the beginning of the example. Pay close attention to how the compiler gives an error and forces you to choose between using a try-catch block or adding a throws declaration. Next, watch the segment on unchecked exceptions, starting from this timestamp. Notice how the code compiles without any errors, but fails at runtime. This highlights that while you can catch them, the primary goal is often to prevent them by writing better code.


2. The Root of the Distinction: The Exception Hierarchy

So, how does Java decide which exceptions are checked and which are unchecked? The answer lies in the class hierarchy. All exceptions and errors in Java inherit from a base class called Throwable. Under Throwable, there are two main branches: Error and Exception.

  • Error: This branch is for serious system-level problems that your application usually cannot recover from, such as OutOfMemoryError or StackOverflowError. You should almost never try to catch these.
  • Exception: This is the branch for all the exceptions we've been discussing. This class itself has a very important subclass: RuntimeException.

This leads to the definitive rule:
Any exception class that inherits from RuntimeException is an UNCHECKED exception. All other classes that inherit directly from Exception are CHECKED exceptions.

This flowchart provides a perfect visual map of the hierarchy.

This diagram shows the Java exception hierarchy. `Throwable` is the parent of both `Error` and `Exception`. The `Error` branch and the `RuntimeException` branch (which is a child of `Exception`) are categorized as **Unchecked Exceptions**. All other direct subclasses of `Exception`, like `IOException`, are **Checked Exceptions**.

The "Coding with John" video also has a concise section that explains this hierarchy, which will help solidify your understanding.

Checked vs. Unchecked Exceptions in Java Tutorial - What's The Difference?

This part of the video connects the concepts of checked and unchecked exceptions directly to the class hierarchy shown in the diagram above.

Please watch the explanation from this point. It directly answers the question of how Java determines which exceptions are which type.


3. Practical Guidelines: Identification and Usage

Now that you understand the "what" and "why," let's focus on the "how." How do you identify an exception's type in practice, and when should you choose to use one over the other in your own code (a more advanced topic, but good to know the principle)?

Identifying an Exception's Type

The most reliable way is to look at the official Java documentation (the Javadoc). The resource from cs1302uga.github.io provides a simple, practical method for this.

3.7. Checked vs. Unchecked Exceptions - CSCI 1302

This section gives you a straightforward process for determining if an exception is checked or unchecked by inspecting its class hierarchy in the Javadoc.

Please read the short section Identifying Checked vs. Unchecked Exceptions. This is a valuable skill for any Java developer when encountering a new exception type.

The Philosophy: When to Use Checked vs. Unchecked

The choice between checked and unchecked exceptions follows a simple but powerful principle based on recoverability. The Baeldung article you'll read below quotes the official Oracle documentation on this.

Checked and Unchecked Exceptions in Java

This article provides the official guidance on the design philosophy behind the two exception types.

Read section 4, titled When to Use. Focus on the core idea: "If a client can reasonably be expected to recover from an exception, make it a checked exception."

In short:

  • Use a checked exception for predictable, but unpreventable, external failures (e.g., "the requested file does not exist"). The caller of your method is forced to create a recovery plan (like prompting the user for a different filename).
  • Use an unchecked exception for internal, programmatic errors or bugs (e.g., "you passed a null argument to my method"). The "recovery" here is for the developer to fix the bug that caused the invalid argument to be passed in the first place.

To bring it all together, this Venn diagram offers a great summary of the key properties of each exception type.

This Venn diagram contrasts Checked and Unchecked Exceptions. Checked exceptions are checked at compile time and are direct subclasses of `Exception` (but not `RuntimeException`). Unchecked exceptions are not checked at compile time and are subclasses of `RuntimeException`. Both are part of the Java `Throwable` class and can cause erroneous behavior if not handled.

Conclusion

You have now explored one of the most distinctive features of the Java language. Understanding the difference between checked and unchecked exceptions is fundamental to writing code that is not only correct but also robust and maintainable.

Let's recap the key takeaways:

  • Checked Exceptions are subclasses of Exception (excluding RuntimeException and its children). The compiler forces you to handle them with try-catch or declare them with throws. They signal recoverable, external error conditions.
  • Unchecked Exceptions are subclasses of RuntimeException. The compiler does not enforce handling. They signal programming errors (bugs) that should ideally be fixed.
  • The class hierarchy is the mechanism that defines whether an exception is checked or unchecked.
  • The guiding principle is recoverability: if the calling code can and should do something about the error, it should be a checked exception.

In our next lesson, we will pivot from the fundamentals of the language to one of its most powerful features: the Java Collections Framework. We will begin by exploring the core interfaces—List, Set, and Map—that provide the foundation for storing and manipulating groups of objects efficiently.