← Back to Home

Checked vs Unchecked Exceptions

Java classifies exceptions into Checked and Unchecked to enforce compile-time safety where appropriate and allow runtime flexibility where necessary. Understanding this distinction is critical for API design, robust code, and interviews.

What Are Checked Exceptions?

Checked exceptions are exceptions that are checked by the compiler at compile time.

Key Characteristics

  • Checked at compile time
  • Must be handled using try-catch or declared using throws
  • Represent recoverable conditions
  • Usually related to external systems (I/O, DB, network)

Examples

  • IOException
  • SQLException
  • ClassNotFoundException
  • FileNotFoundException

Example

void readFile() throws IOException {
    FileReader fr = new FileReader("data.txt");
}
❌ Compile-time error if not handled or declared
✔ Forces developer to think about recovery
          

What Are Unchecked Exceptions?

Unchecked exceptions are not checked by the compiler and occur at runtime.

Key Characteristics

  • Occur at runtime
  • Compiler does not force handling
  • Usually caused by programming errors
  • Extend RuntimeException

Examples

  • NullPointerException
  • ArithmeticException
  • ArrayIndexOutOfBoundsException
  • NumberFormatException

Example

int a = 10 / 0; // ArithmeticException
✔ Compiles successfully
❌ Fails at runtime
          

Exception Hierarchy (Important)

Throwable
 ├── Exception
 │    ├── Checked Exceptions (IOException, SQLException)
 │    └── RuntimeException (Unchecked)
 │         ├── NullPointerException
 │         ├── ArithmeticException
 │         └── IndexOutOfBoundsException
 └── Error
          

Core Differences: Checked vs Unchecked (Interview Favorite)

Aspect Checked Exceptions Unchecked Exceptions
Compiler check ✅ Yes ❌ No
When detected Compile time Runtime
Must handle ✅ Yes ❌ No
Parent class Exception RuntimeException
Cause External / Recoverable Programming bugs
API usage Mandatory handling Optional handling

Handling Requirements

Checked Exception — Mandatory

try {
    FileReader fr = new FileReader("file.txt");
} catch (IOException e) {
    e.printStackTrace();
}
OR

void method() throws IOException { }
          

Unchecked Exception — Optional

int[] arr = new int[3];
System.out.println(arr[5]); // Runtime failure
✔ No compiler enforcement
✔ Better prevented using validations
          

Why Java Introduced Checked Exceptions

  • Forces robust error handling
  • Prevents silent failures
  • Improves reliability of enterprise applications
  • Encourages explicit recovery logic

Why Unchecked Exceptions Exist

  • Avoid cluttering code with excessive try-catch
  • Represent coding mistakes
  • Improve code readability
  • Fail fast during development

Best Practices (Real-World)

Use Checked Exceptions When:

  • Error is recoverable
  • Caller can take corrective action
  • Dealing with external resources

Use Unchecked Exceptions When:

  • Error indicates programming bug
  • Recovery is not meaningful
  • Precondition violations occur

Common Beginner Mistakes

  • Catching Exception everywhere
  • Ignoring checked exceptions using empty catch blocks
  • Converting all exceptions to unchecked
  • Using checked exceptions for programming errors

Interview-Ready Answers

Short Answer

Checked exceptions are verified by the compiler and must be handled, while unchecked exceptions occur at runtime and are not enforced by the compiler.

Detailed Answer

In Java, checked exceptions represent recoverable conditions and must be either handled or declared at compile time. Unchecked exceptions extend RuntimeException and usually indicate programming errors. Java uses this distinction to balance safety and flexibility.

Key Takeaway

Checked exceptions enforce responsibility. Unchecked exceptions enforce correctness. Using the right exception type leads to cleaner APIs, safer code, and better maintainability.

Examples: Checked vs Unchecked Exceptions

1. Checked Exception – Compile-Time Error

import java.io.FileInputStream;

class Demo {
    public static void main(String[] args) {
        // FileInputStream fis = new FileInputStream("data.txt"); // ❌ compile-time error
    }
}
          

Explanation

  • FileNotFoundException is checked
  • Must be handled or declared

2. Handling Checked Exception with try-catch

import java.io.FileInputStream;

class Demo {
    public static void main(String[] args) {
        try {
            new FileInputStream("data.txt");
        } catch (Exception e) {
            System.out.println("Checked exception handled");
        }
    }
}
          

Output

Checked exception handled
          

3. Handling Checked Exception with throws

import java.io.FileInputStream;
import java.io.FileNotFoundException;

class Demo {
    static void read() throws FileNotFoundException {
        new FileInputStream("data.txt");
    }

    public static void main(String[] args) throws FileNotFoundException {
        read();
    }
}
          

Explanation

  • Responsibility passed to caller

4. Unchecked Exception – No Compile-Time Error

class Demo {
    public static void main(String[] args) {
        int a = 10 / 0;
    }
}
          

Explanation

  • ArithmeticException is unchecked
  • Detected only at runtime

5. Catching Unchecked Exception

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("Unchecked exception handled");
        }
    }
}
          

Output

Unchecked exception handled
          

6. Checked Exception in Method Signature

import java.io.IOException;

class Demo {
    static void read() throws IOException {}

    public static void main(String[] args) throws IOException {
        read();
    }
}
          

Explanation

  • Checked exceptions must be declared or handled

7. Unchecked Exception – No throws Needed

class Demo {
    static void calc() {
        int[] a = new int[2];
        a[5] = 10;
    }

    public static void main(String[] args) {
        calc();
    }
}
          

Explanation

  • ArrayIndexOutOfBoundsException is unchecked

8. Exception Propagation – Checked Exception

import java.io.IOException;

class Demo {
    static void m1() throws IOException {
        m2();
    }

    static void m2() throws IOException {
        throw new IOException("IO error");
    }

    public static void main(String[] args) {
        try {
            m1();
        } catch (IOException e) {
            System.out.println("Handled in main");
        }
    }
}
          

Output

Handled in main
          

9. Exception Propagation – Unchecked Exception

class Demo {
    static void m1() {
        m2();
    }

    static void m2() {
        throw new NullPointerException();
    }

    public static void main(String[] args) {
        try {
            m1();
        } catch (Exception e) {
            System.out.println("Unchecked handled");
        }
    }
}
          

Output

Unchecked handled
          

10. Overriding Method – Checked Exception Rule

import java.io.IOException;

class A {
    void show() throws IOException {}
}

class B extends A {
    // void show() throws Exception {} // ❌ not allowed
}
          

Explanation

  • Cannot throw broader checked exception while overriding

11. Overriding Method – Removing Checked Exception

import java.io.IOException;

class A {
    void show() throws IOException {}
}

class B extends A {
    void show() {}   // allowed
}
          

Explanation

  • Child can remove checked exception

12. Overriding Method – Unchecked Exception Allowed

class A {
    void show() {}
}

class B extends A {
    void show() throws RuntimeException {}
}
          

Explanation

  • Unchecked exceptions have no restriction

13. Custom Checked Exception

class InvalidUserException extends Exception {
    InvalidUserException(String msg) {
        super(msg);
    }
}

class Demo {
    static void login(String user) throws InvalidUserException {
        if (!user.equals("admin")) {
            throw new InvalidUserException("Invalid user");
        }
    }

    public static void main(String[] args) throws InvalidUserException {
        login("guest");
    }
}
          

14. Custom Unchecked Exception

class InvalidAmountException extends RuntimeException {
    InvalidAmountException(String msg) {
        super(msg);
    }
}

class Demo {
    static void pay(int amt) {
        if (amt <= 0) {
            throw new InvalidAmountException("Amount invalid");
        }
    }

    public static void main(String[] args) {
        pay(-10);
    }
}
          

15. throw with Checked Exception

import java.io.IOException;

class Demo {
    static void test() throws IOException {
        throw new IOException("IO issue");
    }

    public static void main(String[] args) throws IOException {
        test();
    }
}
          

Explanation

  • Checked exception must be declared

16. throw with Unchecked Exception

class Demo {
    static void test() {
        throw new NullPointerException("Null issue");
    }

    public static void main(String[] args) {
        test();
    }
}
          

Explanation

  • No throws needed

17. Checked Exception in Constructor

import java.io.IOException;

class Demo {
    Demo() throws IOException {
        throw new IOException("Error");
    }

    public static void main(String[] args) throws IOException {
        new Demo();
    }
}
          

18. Unchecked Exception in Constructor

class Demo {
    Demo() {
        throw new ArithmeticException();
    }

    public static void main(String[] args) {
        new Demo();
    }
}
          

19. Common Interview Trap

class Demo {
    static void test() {
        try {
            throw new Exception();
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    public static void main(String[] args) {
        test();
    }
}
          

Explanation

  • Checked exception converted to unchecked

20. Interview Summary – Checked vs Unchecked

class Demo {
    static void checked() throws Exception {}
    static void unchecked() {}

    public static void main(String[] args) throws Exception {
        checked();
        unchecked();
    }
}
          

Key Differences

  • Checked → compile-time check, must handle or declare
  • Unchecked → runtime only, no enforcement
  • Checked → IOException, SQLException
  • Unchecked → NullPointerException, ArithmeticException