Java provides a structured exception handling mechanism based on an inheritance hierarchy. At the top, all exceptions and errors are subclasses of Throwable, which is further divided into Exception and Error.
Top-Level Hierarchy
java.lang.Throwable
├── java.lang.Exception
│ ├── java.lang.RuntimeException
│ │ ├── ArithmeticException
│ │ ├── NullPointerException
│ │ ├── ArrayIndexOutOfBoundsException
│ │ ├── ClassCastException
│ │ ├── IllegalArgumentException
│ │ ├── NumberFormatException
│ │ └── ...
│ ├── IOException
│ │ ├── FileNotFoundException
│ │ ├── EOFException
│ │ └── ...
│ ├── SQLException
│ ├── InterruptedException
│ └── ...
│
└── java.lang.Error
├── StackOverflowError
├── OutOfMemoryError
├── VirtualMachineError
├── AssertionError
├── ...
2. Breakdown of Throwable
2.1 Throwable (Root Class)
- The root class for all exceptions and errors in Java.
- Every exception or error inherits from
Throwable.
3. Exception (Recoverable Exceptions)
- Represents conditions that a program should catch and handle.
- It is further divided into:
- Checked Exceptions (must be handled using
try-catchor declared usingthrows). - Unchecked Exceptions (Runtime exceptions, which can be avoided with proper coding).
- Checked Exceptions (must be handled using
3.1 Checked Exceptions (Compile-Time Exceptions)
- Must be either caught using
try-catchor declared in the method signature usingthrows. - The compiler forces handling of these exceptions.
- Common checked exceptions:
IOException(when file operations fail)SQLException(when database access fails)InterruptedException(when a thread is interrupted)ClassNotFoundException(when a class is not found at runtime)
Example: Checked Exception Handling
import java.io.*;
public class CheckedExceptionExample {
public static void main(String[] args) {
try {
FileReader file = new FileReader("test.txt"); // May throw FileNotFoundException
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
}
}
}
3.2 Unchecked Exceptions (Runtime Exceptions)
- Occur during program execution (runtime).
- They are subclasses of
RuntimeException. - Do not require
try-catchbut should be prevented with better coding practices. - Common unchecked exceptions:
NullPointerException(accessing a null object)ArrayIndexOutOfBoundsException(accessing invalid array index)ArithmeticException(division by zero)ClassCastException(invalid type conversion)IllegalArgumentException(wrong arguments in a method)
Example: Unchecked Exception (Avoiding NullPointerException)
public class UncheckedExceptionExample {
public static void main(String[] args) {
String str = null;
// System.out.println(str.length()); // This will throw NullPointerException
if (str != null) {
System.out.println(str.length()); // Safe approach
} else {
System.out.println("String is null");
}
}
}
4. Error (Non-Recoverable)
- Represents serious problems that a program should not handle.
- Errors usually indicate issues with the JVM, memory, or system resources.
- Common errors:
StackOverflowError(infinite recursion)OutOfMemoryError(insufficient heap memory)VirtualMachineError(JVM failure)AssertionError(failed assertion checks)
Example: StackOverflowError
public class StackOverflowExample {
public static void recursiveMethod() {
recursiveMethod(); // Infinite recursion
}
public static void main(String[] args) {
recursiveMethod(); // This will cause StackOverflowError
}
}
Output:
Exception in thread "main" java.lang.StackOverflowError
5. Summary Table
| Exception Type | Description | Handling Required? | Examples |
|---|---|---|---|
| Checked Exception | Compile-time exceptions | ✅ Yes | IOException, SQLException, InterruptedException |
| Unchecked Exception | Runtime exceptions | ❌ No | NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException |
| Error | Serious system-level errors | 🚫 No | StackOverflowError, OutOfMemoryError |
6. Custom Exceptions
You can create custom exceptions by extending Exception (checked) or RuntimeException (unchecked).
Example: Custom Exception
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void main(String[] args) {
try {
throw new CustomException("This is a custom exception");
} catch (CustomException e) {
System.out.println("Caught: " + e.getMessage());
}
}
}
7. Best Practices for Exception Handling
✔ Use checked exceptions for recoverable conditions, situations not depending on programmer.
✔ Use unchecked exceptions for programming mistakes (e.g., null access), depends on programmer and should be fixed;
✔ Catch specific exceptions instead of Exception or Throwable.
✔ Use finally or try-with-resources to close resources.
✔ Avoid suppressing exceptions with empty catch blocks.
✔ Use meaningful exception messages to ease debugging.