Module 4: Exceptions
Module Overview
Learn about exception handling and error management in Java to create more robust applications.
Learning Objectives
- Understand the purpose of exceptions in Java
- Identify the types of exceptions in Java: checked and unchecked
- Use try-catch blocks to handle exceptions
- Implement try-catch-finally blocks for resource cleanup
- Throw exceptions using the throw statement
- Create custom exception classes for domain-specific errors
- Implement effective exception handling strategies
Exception Basics
What are Exceptions?
Exceptions are events that occur during program execution that disrupt the normal flow of instructions. They represent errors or exceptional conditions that need special handling.
Exception Hierarchy
Java exceptions are organized in a hierarchy with Throwable as the parent class, which has two main subclasses: Error and Exception.
// Exception hierarchy
Throwable
├── Error (unchecked) - serious problems, should not be caught
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── ...
└── Exception
├── IOException (checked)
├── SQLException (checked)
└── RuntimeException (unchecked)
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── ArithmeticException
└── ...
Checked vs. Unchecked Exceptions
Java has two categories of exceptions:
- Checked Exceptions: Must be either caught or declared in the method's throws clause. Example: IOException
- Unchecked Exceptions: Do not need to be explicitly caught or declared. They include RuntimeException and its subclasses, as well as Error and its subclasses. Example: NullPointerException
Handling Exceptions
Try-Catch Blocks
The try-catch block is used to handle exceptions in Java.
// Basic try-catch
try {
// Code that might throw an exception
int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
// Code to handle the exception
System.out.println("Cannot divide by zero: " + e.getMessage());
}
Multiple Catch Blocks
You can use multiple catch blocks to handle different exceptions differently.
try {
// Code that might throw different exceptions
int[] array = new int[5];
array[10] = 30; // ArrayIndexOutOfBoundsException
} catch (ArithmeticException e) {
System.out.println("Arithmetic error: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index error: " + e.getMessage());
} catch (Exception e) {
// Catches any other Exception that wasn't caught above
System.out.println("Some other exception: " + e.getMessage());
}
Try-Catch-Finally
The finally block contains code that will be executed regardless of whether an exception occurs or not. It's commonly used for cleanup operations.
FileReader reader = null;
try {
reader = new FileReader("file.txt");
// Process file
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
} finally {
// This will always execute, even if an exception occurs
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.out.println("Error closing file: " + e.getMessage());
}
}
}
Try-with-Resources
Introduced in Java 7, try-with-resources automatically closes resources that implement AutoCloseable.
// Try-with-resources automatically closes the resource
try (FileReader reader = new FileReader("file.txt")) {
// Process file
// reader is automatically closed when the block completes
} catch (IOException e) {
System.out.println("IO error: " + e.getMessage());
}
Throwing Exceptions
Using the throw Keyword
You can explicitly throw an exception using the throw keyword.
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
this.age = age;
}
Declaring Exceptions with throws
Methods that might throw checked exceptions must declare them using the throws keyword.
public void readFile(String filename) throws IOException {
FileReader reader = new FileReader(filename);
// Process file
reader.close();
}
Creating Custom Exceptions
You can create your own exception classes by extending Exception (for checked exceptions) or RuntimeException (for unchecked exceptions).
// Custom checked exception
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
super("Insufficient funds: Attempted to withdraw " + amount);
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
// Using the custom exception
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException(amount);
}
balance -= amount;
}
Exception Handling Best Practices
Specific Exceptions First
When using multiple catch blocks, catch more specific exceptions before more general ones.
Don't Catch and Ignore
Always handle exceptions meaningfully. Don't catch an exception and do nothing with it (empty catch block).
Clean Up Resources
Use try-with-resources or finally blocks to ensure resources are properly closed.
Document Exceptions
Use JavaDoc to document the exceptions a method may throw.
/**
* Withdraws money from the account.
*
* @param amount the amount to withdraw
* @throws InsufficientFundsException if amount is greater than current balance
*/
public void withdraw(double amount) throws InsufficientFundsException {
// Implementation
}
Exception Translation
Convert low-level exceptions to higher-level ones that make more sense in your application's context.
public void processOrder(Order order) throws OrderProcessingException {
try {
databaseService.saveOrder(order);
} catch (SQLException e) {
// Translate the low-level SQL exception to a domain-specific one
throw new OrderProcessingException("Failed to process order", e);
}
}
Additional Resources
Practice Exercises
Complete these exercises to reinforce your understanding of exceptions.
Exercise 1: Bank Account Exceptions
Create a BankAccount class with the following features:
- Methods for deposit and withdraw
- A custom InsufficientFundsException
- Proper exception handling for invalid inputs
- A transfer method that handles multiple potential exceptions
Exercise 2: File Processing with Exceptions
Create a program that reads and processes a text file:
- Use try-with-resources for file handling
- Handle different types of I/O exceptions
- Implement a custom FileProcessingException
- Add exception logging and recovery strategies