Exception Handling
java exception handling try catch finally throw throws checked unchecked runtime exception try with resources custom exception
Introduction
In every real-world application, unexpected situations can occur during program execution.
For example:
- A user enters invalid input.
- A file does not exist.
- A database connection fails.
- A network request times out.
- A division by zero occurs.
- A required object is
null.
If these situations are not handled properly, the application may terminate unexpectedly, resulting in a poor user experience.
Java provides a powerful Exception Handling mechanism that allows developers to gracefully handle runtime errors without crashing the application.
Exception Handling is one of the most important topics in enterprise Java development and is extensively used in:
- Spring Boot
- Hibernate
- REST APIs
- Banking Systems
- E-Commerce Applications
- Android Development
- Microservices
- Distributed Systems
In this lesson, you'll learn:
- What is an Exception?
- Exception Hierarchy
- Errors vs Exceptions
- Checked vs Unchecked Exceptions
trycatchfinally- Multiple Catch Blocks
- Multi-Catch
throwthrows- Custom Exceptions
- Try-with-Resources
- Exception Chaining
- Best Practices
- Common Mistakes
- Real-world Examples
- Professional Interview Questions
What is an Exception?
An Exception is an event that interrupts the normal flow of program execution.
Example:
int result = 10 / 0;
Output:
Exception in thread "main"java.lang.ArithmeticException: / by zero
Without exception handling, the program terminates immediately.
Why Exception Handling?
Without exception handling:
Program Starts↓Exception Occurs↓Application Crashes
With exception handling:
Program Starts↓Exception Occurs↓Catch Exception↓Continue Execution
Benefits:
- Prevents application crashes
- Improves user experience
- Simplifies debugging
- Separates business logic from error handling
- Makes applications more reliable
Exception Hierarchy
Java exceptions are organized in a hierarchy.
Object│Throwable/ \Error Exception│RuntimeException
Throwableis the root class.Errorrepresents serious JVM problems.Exceptionrepresents conditions that applications can handle.RuntimeExceptionrepresents programming errors detected at runtime.
Error vs Exception
| Error | Exception |
|---|---|
| Caused by JVM | Caused by application or external factors |
| Usually unrecoverable | Usually recoverable |
| Should not be caught in normal applications | Should be handled appropriately |
Example: OutOfMemoryError | Example: IOException |
Checked Exceptions
Checked exceptions are verified by the compiler.
Example:
import java.io.FileReader;public class Demo {public static void main(String[] args) {FileReader reader =new FileReader("data.txt");}}
Compilation Error:
Unhandled exception:FileNotFoundException
The compiler forces you to handle or declare checked exceptions.
Common Checked Exceptions:
- IOException
- SQLException
- FileNotFoundException
- ClassNotFoundException
Unchecked Exceptions
Unchecked exceptions occur during runtime.
Example:
String text = null;System.out.println(text.length());
Output:
NullPointerException
Common Runtime Exceptions:
- NullPointerException
- ArithmeticException
- ArrayIndexOutOfBoundsException
- NumberFormatException
- IllegalArgumentException
The try Block
The try block contains code that may throw an exception.
try {int result = 10 / 0;}
The catch Block
The catch block handles the exception.
try {int result = 10 / 0;}catch (ArithmeticException ex) {System.out.println("Cannot divide by zero.");}
Output:
Cannot divide by zero.
The finally Block
The finally block always executes, whether an exception occurs or not.
try {System.out.println("Opening File");}finally {System.out.println("Closing File");}
Output:
Opening FileClosing File
Typical use cases:
- Closing files
- Releasing database connections
- Closing network sockets
- Cleaning resources
Complete Example
try {int[] numbers = {1,2,3};System.out.println(numbers[5]);}catch(ArrayIndexOutOfBoundsException ex){System.out.println("Invalid Index");}finally{System.out.println("Execution Finished");}
Output:
Invalid IndexExecution Finished
Multiple Catch Blocks
Different exceptions can be handled separately.
try {String text = null;System.out.println(text.length());}catch(NullPointerException ex){System.out.println("Null Value");}catch(Exception ex){System.out.println("General Exception");}
Always place more specific exceptions before more general ones.
Multi-Catch (Java 7+)
If multiple exceptions require identical handling:
try {// Code}catch(ArithmeticException |NumberFormatException ex){System.out.println("Invalid Input");}
This reduces duplicate code.
The throw Keyword
throw explicitly throws an exception.
Example:
public void withdraw(double amount){if(amount < 0){throw new IllegalArgumentException("Amount cannot be negative");}}
Output:
IllegalArgumentException:Amount cannot be negative
The throws Keyword
throws declares that a method may propagate an exception to its caller.
import java.io.IOException;public void readFile()throws IOException {}
The calling method must then handle or declare the exception.
throw vs throws
| throw | throws |
|---|---|
| Throws an exception object | Declares possible exceptions |
| Used inside a method | Used in the method signature |
| Throws one exception instance | Can declare multiple exception types |
Custom Exceptions
Custom exceptions represent application-specific business errors.
Example:
class InsufficientBalanceExceptionextends Exception {public InsufficientBalanceException(String message){super(message);}}
Using it:
if(balance < amount){throw new InsufficientBalanceException("Insufficient Balance");}
Custom exceptions make business rules easier to understand and maintain.
Try-with-Resources (Java 7+)
Automatically closes resources that implement AutoCloseable.
import java.io.BufferedReader;import java.io.FileReader;try(BufferedReader reader =new BufferedReader(new FileReader("data.txt"))){System.out.println(reader.readLine());}catch(Exception ex){System.out.println(ex.getMessage());}
Benefits:
- Automatic resource cleanup
- Less boilerplate code
- Prevents resource leaks
Exception Chaining
One exception can wrap another.
Example:
try{// Database Code}catch(Exception ex){throw new RuntimeException("Database Error", ex);}
This preserves the original cause while providing additional context.
Real-World Example: Banking System
public void withdraw(double amount)throws InsufficientBalanceException{if(amount > balance){throw new InsufficientBalanceException("Balance too low");}balance -= amount;}
Real-World Example: REST API
try{service.save(employee);}catch(Exception ex){return ResponseEntity.internalServerError().build();}
In Spring Boot, centralized exception handling is commonly implemented using @ControllerAdvice and @ExceptionHandler.
Best Practices
Catch Specific Exceptions
Prefer:
catch(IOException ex)
Instead of:
catch(Exception ex)
Specific exception handling improves clarity and avoids masking unrelated issues.
Never Ignore Exceptions
Avoid:
catch(Exception ex){}
Always log, wrap, or handle exceptions appropriately.
Use Custom Exceptions for Business Rules
Domain-specific exceptions improve readability and make business logic easier to understand.
Use Try-with-Resources
Prefer automatic resource management for files, sockets, and database resources.
Preserve the Root Cause
When wrapping exceptions, pass the original exception as the cause.
Common Mistakes
Catching Exception Everywhere
Overly broad exception handling can hide programming mistakes.
Swallowing Exceptions
Ignoring exceptions makes debugging extremely difficult.
Using Exceptions for Normal Flow Control
Exceptions should represent exceptional situations, not regular business logic.
Forgetting Resource Cleanup
Always release resources using try-with-resources or finally.
Losing Stack Trace Information
Avoid creating a new exception without preserving the original cause when appropriate.
Hands-on Exercise
Create a Java program that:
- Demonstrates
ArithmeticException. - Handles
NullPointerException. - Reads a file using try-with-resources.
- Creates multiple catch blocks.
- Uses multi-catch for two exception types.
- Creates a custom
InvalidAgeException. - Demonstrates the use of
throwandthrows. - Wraps an exception using exception chaining.
Summary
Exception handling enables Java applications to respond gracefully to unexpected situations. By using try, catch, finally, throw, throws, custom exceptions, and try-with-resources, developers can build reliable, maintainable, and production-ready software. Proper exception handling is essential in enterprise applications and helps separate business logic from error recovery.
Key Takeaways
- Exceptions interrupt the normal flow of execution.
Throwableis the root of Java's exception hierarchy.- Checked exceptions are verified by the compiler.
- Unchecked exceptions occur at runtime.
tryencloses risky code.catchhandles exceptions.finallyexecutes regardless of success or failure.throwexplicitly creates and throws an exception.throwsdeclares exceptions in a method signature.- Try-with-resources automatically closes resources.
- Custom exceptions improve business logic clarity.
- Preserve exception causes when wrapping exceptions.
Professional Interview Questions
1What is the difference between Checked and Unchecked Exceptions?
Professional Answer
Checked exceptions are validated by the compiler and must either be handled using a try-catch block or declared using the throws keyword. They typically represent recoverable conditions such as file or database access failures. Unchecked exceptions extend RuntimeException and occur during program execution, usually indicating programming errors such as null references or invalid array indexes.
Follow-up Questions
- Why are checked exceptions called compile-time exceptions?
- Give three examples of runtime exceptions.
Interview Tip: Remember: Checked = Compiler forces handling, Unchecked = Runtime programming errors.
2What is the difference between throw and throws?
Professional Answer
The throw keyword is used inside a method to explicitly create and throw an exception object. The throws keyword is used in a method declaration to indicate that the method may propagate one or more exceptions to its caller.
Follow-up Questions
- Can a method declare multiple exceptions with throws?
- Can you throw checked and unchecked exceptions?
Interview Tip: A simple rule: throw → Action, throws → Declaration.
3What is Try-with-Resources, and why is it preferred?
Professional Answer
Try-with-resources is a Java feature introduced in Java 7 that automatically closes resources implementing the AutoCloseable interface after execution. It reduces boilerplate code, prevents resource leaks, and ensures resources are released even if an exception occurs.
Follow-up Questions
- Which interface must a resource implement?
- Can multiple resources be declared in a single try-with-resources statement?
Interview Tip: Prefer try-with-resources over manual cleanup in finally whenever working with files, streams, sockets, or database connections.