Exception handling is a powerful feature in Java that enables applications to detect, handle, and recover from runtime errors gracefully. Proper exception handling improves application reliability, maintainability, and debugging.
What is an Exception?
An exception is an event that occurs during program execution and disrupts the normal flow of instructions.
Examples include:
- Reading a missing file
- Database connection failure
- Division by zero
- Accessing a null object
- Invalid user input
History of Exception Handling in Java
- Introduced in Java 1.0 with Throwable, Exception, and Error classes.
- Java’s design emphasized compile-time exception checking.
- Java 7 introduced Try-With-Resources for automatic resource management & multi-catch blocks.
- Java 14+ added Helpful NullPointerExceptions for easier debugging and error diagnosis.
Types of Exceptions in Java
Java categorizes exceptions into three main types:
1. Checked Exceptions
Checked exceptions are verified at compile time.
The compiler requires developers to either:
- Handle the exception using try-catch
- Declare it using the throws keyword
These exceptions usually occur due to external resources or environmental issues and are generally recoverable.
Examples
Exception | Why It Occurs |
IOException | File, network, or stream operation fails |
SQLException | Database access or query execution fails |
ClassNotFoundException | JVM cannot find a class during dynamic loading |
FileNotFoundException | Requested file does not exist |
InterruptedException | A thread is interrupted while waiting or sleeping |
2. Unchecked Exceptions Its programmer's mistake
Unchecked exceptions occur at runtime and are not verified by the compiler.
They usually indicate programming mistakes, invalid application state, or missing validations.
Examples
Exception | Why It Occurs |
NullPointerException | Accessing a method or field on a null reference |
ArithmeticException | Illegal arithmetic operation such as divide by zero |
ArrayIndexOutOfBoundsException | Accessing an invalid array index |
NumberFormatException | Parsing an invalid numeric string |
ClassCastException | Casting an object to an incompatible type |
IllegalArgumentException | Passing an invalid argument to a method |
IllegalStateException | Method invoked at an inappropriate time or state |
Note: Runtime exceptions usually indicate bugs in application logic and should be prevented through proper validation and coding practices.
3. Errors
Errors represent serious JVM-level problems that applications generally should not attempt to handle.
They usually indicate resource exhaustion or JVM failures.
Examples
Error | Why It Occurs |
OutOfMemoryError | JVM runs out of available memory |
StackOverflowError | Infinite or very deep recursion exhausts the call stack |
InternalError | Unexpected failure within the JVM |
NoClassDefFoundError | Required class is missing at runtime |
UnsupportedClassVersionError | Class compiled with a newer Java version than the JVM supports |
Note: Errors are generally unrecoverable and should be fixed by addressing system, configuration, deployment, or JVM-related issues rather than by adding exception handling code.
Throwable
|── Error → Serious JVM/System Failure
| Example: JVM runs out of memory.
| Usually not recoverable.
|── Exception
|
|── Checked Exception → External/Recoverable Problem
| Example: Database server is temporarily down or file not found.
| Not a programmer's mistake, but the application
| should anticipate and handle such scenarios.
|
|── RuntimeException → Programming Mistake / Logic Error
Example: Accessing a null object reference.
Java Exception Hierarchy
Checked vs Unchecked Exceptions
Feature | Checked Exception | Unchecked Exception |
Compile-time check | Yes | No |
Base class | Exception (excluding RuntimeException) | RuntimeException and subclasses |
When it occurs | External events | Logic/programming errors |
Handling required? | Yes (must catch or declare) | No (optional) |
Examples | IOException, SQLException | NullPointerException, ArithmeticException |
Programmer's mistake? | Usually not | Yes – logic bug |
Exception Handling Keywords
Keyword | Purpose |
try | Defines a block of code that may throw an exception |
catch | Handles exceptions thrown from the try block |
finally | Executes whether an exception occurs or not; typically used for cleanup |
throw | Explicitly throws an exception |
throws | Declares exceptions that a method may throw |
Common Programmer Errors (Runtime Exceptions)
Exception | Example |
NullPointerException | Accessing an object without a null check |
ArrayIndexOutOfBoundsException | Using an invalid array index |
NumberFormatException | Parsing "abc" as an integer |
ClassCastException | Invalid object casting |
IllegalArgumentException | Passing an invalid method argument |
Note: Runtime exceptions usually indicate bugs in application logic and should be prevented through proper validation and coding practices.
When to Use Checked vs Unchecked Exceptions?
Use Case | Type | Reason |
Reading files, databases, or network resources | Checked | External resources may fail |
Reflection and dynamic class loading | Checked | Resource availability is uncertain |
Division operations | Unchecked | Programming logic issue |
Parsing user input | Unchecked | Input should be validated |
Null checks | Unchecked | Developer responsibility |
Array/List indexing | Unchecked | Bounds should be validated |
Real-World Use Cases
Scenario | Exception Type | Description |
Reading a file | IOException | File not found or read failure |
Connecting to a database | SQLException | Database connection failure |
Parsing user input | NumberFormatException | Invalid numeric format |
Division by zero | ArithmeticException | Invalid arithmetic operation |
Accessing a null object | NullPointerException | Object reference is null |
Invalid array index | ArrayIndexOutOfBoundsException | Index outside valid range |
Reflection failure | ClassNotFoundException | Class not available at runtime |
Real-Time Exception Handling Examples
1. Checked Exception Example
try {
BufferedReader br =
new BufferedReader(new FileReader("data.txt"));
String line = br.readLine();
br.close();
} catch (IOException e) {
System.out.println(
"File handling error: " + e.getMessage()
);
}
Use Case: Reading a file
What can go wrong?
- File not found
- Permission issue
- Read failure
Why Checked?
The problem is external and recoverable. Once the file becomes available, the operation can succeed.
2. Unchecked Exception Example
int a = 10;
int b = 0;
int result = a / b;
Exception: ArithmeticException
Why?
Division by zero is a programming error and should be prevented through validation.
3. try-catch-finally Example
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
} finally {
System.out.println("This block always executes.");
}
Purpose
- try → Risky code
- catch → Handle exception
- finally → Cleanup code
4. Multiple Catch Blocks Example
try {
int[] arr = new int[3];
arr[4] = 10;
} catch (ArithmeticException e) {
System.out.println("Arithmetic error!");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index error!");
}
Purpose
Handle different exception types differently.
5. throw and throws Example
public static void main(String[] args)
throws Exception {
checkAge(15);
}
static void checkAge(int age)
throws Exception {
if (age < 18) {
throw new Exception(
"Underage - Access Denied"
);
}
}
Purpose
- throw → Create and throw an exception
- throws → Declare exceptions that a method may throw
6. Custom Exception Example
class InvalidAgeException extends Exception {
public InvalidAgeException(
String message) {
super(message);
}
}
Usage
if (age < 18) {
throw new InvalidAgeException(
"Not eligible to vote"
);
}
Purpose
Represent business-specific validation errors.
7. Try-With-Resources Example
try (
BufferedReader reader =
new BufferedReader(
new FileReader("data.txt")
)
) {
System.out.println(
reader.readLine()
);
} catch (IOException e) {
e.printStackTrace();
}
Purpose
Automatically closes resources after use and prevents resource leaks.
Framework-Specific Exception Handling
Spring Boot
- @ControllerAdvice for global exception handling
- @ExceptionHandler for handling specific exceptions
- ResponseEntity for custom REST error responses
JDBC / Hibernate / JPA
- SQLException
- DataAccessException
- PersistenceException
Servlets / Web Applications
- Custom error pages (web.xml)
- @WebFilter
- Exception mappers
JUnit Exception Testing
- assertThrows(IOException.class, () -> {
myService.readFile("missing.txt");
});
Interfaces Used in Java Exception Framework
Interface | Description |
Serializable | All exceptions implement this interface for serialization |
AutoCloseable | Used by Try-With-Resources for automatic cleanup |
Closeable | Extended by I/O resources such as FileReader and InputStream |
Best Practices
- Catch specific exceptions instead of generic Exception
- Use custom exceptions for business validation failures
- Prefer Try-With-Resources for I/O operations
- Log exceptions using SLF4J or Log4j instead of printStackTrace()
- Preserve the original exception cause when rethrowing exceptions
- Validate user input before processing
- Never use empty catch blocks
- Avoid catching Throwable, Error, or overly generic exceptions
Common Pitfalls
- Catching Exception everywhere without understanding the root cause
- Swallowing exceptions silently
- Using exceptions for normal program flow
- Returning from a finally block
- Forgetting to close resources
- Using empty catch blocks
Quick Summary
Category | Examples | Use Cases |
Error | OutOfMemoryError, StackOverflowError | Unrecoverable JVM/System failures |
Checked Exception | IOException, SQLException, ClassNotFoundException | Recoverable external failures |
Runtime Exception | NullPointerException, IllegalArgumentException | Programming and validation errors |
Conclusion
Java exception handling enables applications to detect, handle, and recover from unexpected situations gracefully. Understanding checked exceptions, runtime exceptions, errors, exception hierarchy, and exception handling best practices helps developers build reliable, maintainable, and production-ready applications.