Checked vs Unchecked Exceptions

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • Checked Exceptions (Compile-Time): Exceptions that the compiler forces you to handle (using try-catch or throws). Used for recoverable external issues (e.g., IOException).
  • Unchecked Exceptions (Run-Time): Exceptions that extend RuntimeException. The compiler ignores them. Used for programming errors (e.g., NullPointerException).

Concept

Java designers believed that if a program interacts with the outside world (like opening a file or connecting to a database), failure is inevitable. The disk might be full, or the network might be down. They created Checked Exceptions to force developers to write contingency plans (catch blocks) for these scenarios before the code is even allowed to compile.

However, a NullPointerException or an IndexOutOfBoundsException is not a network failure; it’s a bug written by the developer. It makes no sense to wrap every single variable access in a try-catch block just in case it’s null. These are Unchecked Exceptions. The program should simply crash so the developer can fix the code.

Note: Modern frameworks (like Spring) convert almost all Checked exceptions into Unchecked exceptions, because forcing developers to write boilerplate try-catch blocks everywhere is widely considered a failed experiment in language design.

Examples

import java.io.*;

public class ExceptionDemo {

    // 1. CHECKED EXCEPTION
    // FileReader throws FileNotFoundException (which is a Checked Exception).
    // The compiler WILL NOT COMPILE this code unless we add a throws clause or a try-catch.
    public void readFile() throws FileNotFoundException {
        FileReader file = new FileReader("C:\\data.txt");
    }

    // 2. UNCHECKED EXCEPTION
    // Trying to access index 100 on an array of size 5 will throw an 
    // ArrayIndexOutOfBoundsException (an Unchecked Exception). 
    // The compiler allows this to compile perfectly fine. It will just crash at runtime.
    public void crashProgram() {
        int[] arr = {1, 2, 3};
        System.out.println(arr[100]); 
    }
}

Interview Questions

Q: Should I create Custom Checked or Custom Unchecked exceptions?
A: In modern Java development, you should almost exclusively create Custom Unchecked Exceptions (by extending RuntimeException).
If you create a Checked Exception, every single method in the call stack that calls your code must declare throws MyException. If you change the method signature later, you break the entire application. Unchecked exceptions keep the code clean and prevent boilerplate try-catch clutter.

Q: How does Spring handle database exceptions?
A: JDBC natively throws SQLException, which is a Checked Exception. This means every time you query a database, Java forces you to write a massive try-catch block.
Spring Framework intercepts the Checked SQLException, hides it, and throws a custom DataAccessException instead, which is an Unchecked Exception. This allows developers to write clean database code without boilerplate, while utilizing global Exception Handlers (@ControllerAdvice) to handle failures elegantly at the web layer.