Getty Images

What are checked vs. unchecked exceptions in Java?

Understand the difference between checked and unchecked exceptions in Java, and learn how to handle these problem conditions properly and gracefully.

Some exceptions in Java must be handled in the developer's code. Other exceptions can occur without any exception handling semantics at all. When an exception must be handled with try-and-catch semantics, it is known as a checked exceptions. If try-and-catch semantics are not required, it is known as an unchecked exception.

Checked exception example

A checked exception in Java represents a predictable, erroneous situation that can occur even if a software library is used as intended.

For example, if a developer tries to access a file, the Java IO library forces them to deal with the checked FileNotFoundException. The developers of the Java IO API anticipated that attempting to access a file that does not exist would be a relatively common occurrence, so they created a checked exception to force a developer to deal with it.

Unchecked exception example

In contrast to a checked exception, an unchecked exception represents an error in programming logic, not an erroneous situation that might reasonably occur during the proper use of an API.

Because the compiler can't anticipate logical errors that arise only at runtime, it can't check for these types of problems at compile time. That's why they are called "unchecked" exceptions.

Unchecked exceptions result from faulty logic that can occur anywhere in a software program. For example, if a developer invokes a method on a null object, an unchecked NullPointerException occurs. If a developer attempts to access an array element that does not exist, the unchecked ArrayIndexOutOfBoundsException occurs.

Compare checked vs. unchecked exceptions

Criteria Unchecked exception Checked exception
Purpose Unanticipated errors in logic that show up at runtime Anticipated problems associated with the normal use of an API
Ancestry Includes RuntimeException Does not include RuntimeException
Handling Exception handling semantics are not required Must be handled in a try-and-catch block, or be thrown by the invoking method
Extension Can be customized by extending RuntimeException Can be customized by extending java.lang.Exception
List of examples NullPointerException, ClassCastException, ArithmeticException, DateTimeException, ArrayStoreException ClassNotFoundException, SocketException, SQLException, IOException, FileNotFoundException

Handling checked and unchecked exceptions

The following example contrasts checked and unchecked exceptions.

public static void main(String[] args) {
 
 /* checked vs unchecked exception example */
 try {
  Class.forName("com.mcnz.Example");
 } catch (ClassNotFoundException e) {
  System.out.println("Class was not found.");
 }
    
 String input = null;
 input.length(); // throws an unchecked exception
    
}

First, the Class.forName() method loads the class named com.mcnz.CheckedClass into the JVM. The API developer knows there's a possibility that the class may not exist, so the developer is forced to handle the ClassNotFoundException through try-and-catch semantics.

As the code executes, the forName() method may never actually throw a ClassNotFoundException. Nevertheless, the developer is forced to handle this checked condition.

Now look at the assignment of the String named input to null, and the subsequent length(). This input.length() invocation triggers a NullPointerException and causes the program to fail every time it runs. This is an unchecked exception caused by poor programming practices that are not revealed until the program executes. Therefore, it requires no exception handling semantics.

Modern use of unchecked exceptions

The technical description of checked vs. unchecked exceptions provided in this article are in line with the manner in which the creators of the Java language envisioned their use. However, the syntactic ceremony associated with handling checked exceptions, especially when there is little chance to recover from them, tends to make Java code more verbose, less readable and more difficult to maintain.

The general trend in the industry is to move away from the extensive creation of checked exceptions in an API or framework.

Many frameworks, including Spring, simply capture checked exceptions and then rethrow them as unchecked exceptions. A global exception harness then catches all unchecked exceptions and performs generic exception handling and recover routines.

Dig Deeper on Development tools for continuous software delivery