Classification of Exceptions

Introduction

Java exceptions are classified into three main types: Checked Exceptions, Unchecked Exceptions, and Errors.


Exception Hierarchy

java.lang.Object
    └── java.lang.Throwable
         ├── java.lang.Error
         └── java.lang.Exception
              ├── RuntimeException (Unchecked)
              └── Other Exceptions (Checked)

Three Types

1. Checked Exceptions

  • Checked at compile time
  • Must handle or declare
  • Recoverable conditions

2. Unchecked Exceptions (RuntimeException)

  • Not checked at compile time
  • Optional to handle
  • Programming errors

3. Errors

  • Serious problems
  • Don’t catch
  • System failures

1. Checked Exceptions

Checked by compiler at compile time.

Must:

  • Handle with try-catch, OR
  • Declare with throws

Common Checked Exceptions:

ExceptionCause
IOExceptionI/O operation failed
FileNotFoundExceptionFile doesn’t exist
SQLExceptionDatabase error
ClassNotFoundExceptionClass not found
InterruptedExceptionThread interrupted
ParseExceptionDate/number parsing failed

Checked Exception Example

import java.io.*;

public class Main {
    public static void main(String[] args) {
        // ✗ Won't compile - must handle IOException
        // FileReader fr = new FileReader("test.txt");

        // ✓ Option 1: Handle with try-catch
        try {
            FileReader fr = new FileReader("test.txt");
            fr.close();
        } catch (IOException e) {
            System.out.println("File error: " + e.getMessage());
        }
    }
}
import java.io.*;

public class Main {
    // ✓ Option 2: Declare with throws
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("test.txt");
        fr.close();
    }
}

2. Unchecked Exceptions

Not checked at compile time (RuntimeException and subclasses).

Optional to handle - usually programming bugs.

Common Unchecked Exceptions:

ExceptionCause
ArithmeticExceptionDivision by zero
NullPointerExceptionUsing null reference
ArrayIndexOutOfBoundsExceptionInvalid array index
NumberFormatExceptionInvalid string to number
IllegalArgumentExceptionInvalid method argument
ClassCastExceptionInvalid type cast
IllegalStateExceptionInvalid object state

Unchecked Exception Examples

ArithmeticException:

public class Main {
    public static void main(String[] args) {
        // No compile error, but runtime exception
        int result = 10 / 0;  // ArithmeticException
    }
}

NullPointerException:

public class Main {
    public static void main(String[] args) {
        String str = null;
        System.out.println(str.length());  // NullPointerException
    }
}

ArrayIndexOutOfBoundsException:

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(arr[5]);  // ArrayIndexOutOfBoundsException
    }
}

3. Errors

Serious problems that applications should not catch.

Indicates system failures beyond application control.

Common Errors:

ErrorCause
OutOfMemoryErrorHeap full
StackOverflowErrorStack full (infinite recursion)
VirtualMachineErrorJVM error
AssertionErrorAssertion failed
NoClassDefFoundErrorClass definition not found
LinkageErrorLinking problem

Error Examples

StackOverflowError:

public class Main {
    static void recursiveMethod() {
        recursiveMethod();  // Infinite recursion
    }

    public static void main(String[] args) {
        recursiveMethod();  // StackOverflowError
    }
}

OutOfMemoryError:

public class Main {
    public static void main(String[] args) {
        int[] arr = new int[Integer.MAX_VALUE];  // OutOfMemoryError
    }
}

Note: Don’t catch Errors in normal code.


Comparison Table

FeatureCheckedUncheckedError
ParentExceptionRuntimeExceptionError
Compile checkYesNoNo
Must handleYesNoNo
When occursExternal issuesProgramming bugsSystem failures
RecoverableYesMaybeNo
ExampleIOExceptionNullPointerExceptionStackOverflowError
Should catchYesOptionalNo

Checked vs Unchecked Example

import java.io.*;

public class Main {
    public static void main(String[] args) {
        // CHECKED - Must handle
        try {
            FileReader fr = new FileReader("test.txt");
        } catch (FileNotFoundException e) {  // Checked exception
            System.out.println("File not found");
        }

        // UNCHECKED - Optional to handle
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {  // Unchecked exception
            System.out.println("Cannot divide by zero");
        }

        // Can also not handle unchecked:
        String str = "Hello";
        System.out.println(str.length());  // No try-catch needed
    }
}

When to Use Each Type?

Checked Exceptions:

Use for recoverable external conditions:

  • File operations
  • Network operations
  • Database operations
  • User input validation

Unchecked Exceptions:

Use for programming errors:

  • Invalid arguments
  • Null references
  • Array bounds
  • Type casting issues

Errors:

Don’t use - JVM generates:

  • Memory issues
  • Stack overflow
  • Class loading problems

Complete Example

import java.io.*;

public class ExceptionDemo {
    // Method with checked exception
    static void readFile(String filename) throws IOException {
        FileReader fr = new FileReader(filename);  // Checked
        System.out.println("File opened");
        fr.close();
    }

    // Method with unchecked exception
    static void divide(int a, int b) {
        int result = a / b;  // May throw ArithmeticException (unchecked)
        System.out.println("Result: " + result);
    }

    // Recursive method - may cause StackOverflowError
    static void recurse(int n) {
        System.out.println(n);
        recurse(n + 1);  // May cause Error
    }

    public static void main(String[] args) {
        // Handling checked exception
        try {
            readFile("data.txt");
        } catch (IOException e) {
            System.out.println("File error: " + e.getMessage());
        }

        // Handling unchecked exception
        try {
            divide(10, 0);
        } catch (ArithmeticException e) {
            System.out.println("Math error: " + e.getMessage());
        }

        // Don't normally catch errors
        // recurse(1);  // Will cause StackOverflowError
    }
}

RuntimeException Hierarchy

RuntimeException
├── ArithmeticException
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── StringIndexOutOfBoundsException
├── NumberFormatException
├── IllegalArgumentException
├── IllegalStateException
├── ClassCastException
└── UnsupportedOperationException

Exception vs Error

Exception:

try {
    FileReader fr = new FileReader("test.txt");
} catch (FileNotFoundException e) {
    // Can recover - create file, ask user, etc.
    System.out.println("File not found, using default data");
}

Error:

// DON'T DO THIS
try {
    recursiveMethod();
} catch (StackOverflowError e) {
    // Can't recover - system problem
    // Should fix code, not catch error
}

Creating Custom Exceptions

Custom Checked Exception:

// Extends Exception (checked)
class InvalidAgeException extends Exception {
    InvalidAgeException(String message) {
        super(message);
    }
}

class Voter {
    static void checkAge(int age) throws InvalidAgeException {
        if (age < 18) {
            throw new InvalidAgeException("Age must be 18+");
        }
        System.out.println("Valid voter");
    }
}

Custom Unchecked Exception:

// Extends RuntimeException (unchecked)
class InvalidAmountException extends RuntimeException {
    InvalidAmountException(String message) {
        super(message);
    }
}

class BankAccount {
    static void withdraw(double amount) {
        if (amount < 0) {
            throw new InvalidAmountException("Amount cannot be negative");
        }
        System.out.println("Withdrawal: " + amount);
    }
}

Real-World Scenario

import java.io.*;
import java.util.*;

public class StudentGradeSystem {
    // Checked exception - file operations
    static void loadGrades(String filename) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(filename));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }

    // Unchecked exception - invalid input
    static void calculateGrade(int marks) {
        if (marks < 0 || marks > 100) {
            throw new IllegalArgumentException("Marks must be 0-100");
        }
        String grade = (marks >= 90) ? "A" : (marks >= 75) ? "B" : "C";
        System.out.println("Grade: " + grade);
    }

    public static void main(String[] args) {
        // Handle checked exception
        try {
            loadGrades("grades.txt");
        } catch (FileNotFoundException e) {
            System.out.println("Grade file not found");
        } catch (IOException e) {
            System.out.println("Error reading grades");
        }

        // Handle unchecked exception
        try {
            calculateGrade(150);  // Invalid marks
        } catch (IllegalArgumentException e) {
            System.out.println("Invalid marks: " + e.getMessage());
        }
    }
}

Choosing Exception Type

Create Checked Exception when:

  • Caller can recover
  • External condition (file, network, DB)
  • Expected exceptional situation

Create Unchecked Exception when:

  • Programming error
  • Invalid method arguments
  • Illegal state
  • Shouldn’t normally happen

Quick Reference

// Checked Exception (must handle)
try {
    FileReader fr = new FileReader("file.txt");
} catch (FileNotFoundException e) {
    // Must handle
}

// OR declare with throws
void method() throws IOException {
    FileReader fr = new FileReader("file.txt");
}

// Unchecked Exception (optional)
int result = 10 / 0;  // May throw ArithmeticException
// OR handle if needed
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    // Optional handling
}

// Error (don't catch normally)
// Just fix the code causing the error

Common Mistakes

// ✗ Wrong - catching Error
try {
    // code
} catch (Error e) {
    // Don't do this
}

// ✗ Wrong - declaring unchecked with throws (unnecessary)
void method() throws NullPointerException {
    // No need to declare unchecked
}

// ✓ Correct - handle checked, optional for unchecked
try {
    FileReader fr = new FileReader("file.txt");  // Checked - must handle
    int result = 10 / 0;  // Unchecked - optional
} catch (FileNotFoundException e) {
    // Handle checked
} catch (ArithmeticException e) {
    // Optional: handle unchecked
}

Exam Tips

Remember:

  1. Three types: Checked, Unchecked, Error
  2. Checked - must handle or declare
  3. Unchecked - RuntimeException subclasses
  4. Error - don’t catch normally
  5. IOException - checked
  6. ArithmeticException - unchecked
  7. NullPointerException - unchecked
  8. StackOverflowError - error
  9. Checked for external conditions
  10. Unchecked for programming errors

Common Questions:

  • Types of exceptions?
  • Checked vs unchecked?
  • What are Errors?
  • Examples of checked exceptions?
  • Examples of unchecked exceptions?
  • When to use checked?
  • When to use unchecked?
  • Should we catch Errors?
  • RuntimeException is checked or unchecked?
  • IOException is checked or unchecked?