Object Oriented Programming with JavaUnit 69 min read
Exception Handling: Try-Catch, Throw, Custom Exceptions, and Best Practices
Unit 6 of Object Oriented Programming with Java covers exception handling mechanisms, including checked vs. unchecked exceptions, try-catch-finally blocks, throw and throws, custom exceptions, and best practices for robust error handling in Java applications.
Key Concepts and Definitions
What is an Exception?
An exception is an unexpected or exceptional event that disrupts the normal flow of a program. Java provides a structured way to handle these events using exception handling.
Types of Exceptions
Exceptions in Java are categorized into two main types:
- Checked Exceptions: Compile-time exceptions (e.g.,
IOException,SQLException). The compiler forces you to handle them. - Unchecked Exceptions: Runtime exceptions (e.g.,
NullPointerException,ArrayIndexOutOfBoundsException). The compiler does not enforce handling.
classDiagram
class Exception {
<<abstract>>
+handle()
}
class RuntimeException {
<<extends>>
+unchecked
}
class IOException {
<<extends>>
+checked
}
class SQLException {
<<extends>>
+checked
}
Exception <|-- RuntimeException
Exception <|-- IOException
Exception <|-- SQLExceptionThe Exception Hierarchy
graph TD
A["Throwable"] --> B["Error"]
A --> C["Exception"]
C --> D["Checked Exception"]
C --> E["Unchecked Exception"]
D --> F["IOException"]
D --> G["SQLException"]
E --> H["RuntimeException"]
E --> I["NullPointerException"]
E --> J["ArrayIndexOutOfBoundsException"]Exception Handling Mechanisms
1. try-catch-finally Block
The try block contains code that might throw an exception. The catch block handles the exception, and the finally block executes regardless of whether an exception occurs.
Syntax:
try {
// Code that may throw an exception
} catch (ExceptionType e) {
// Handle the exception
} finally {
// Cleanup code (e.g., closing resources)
}
Example: Handling ArithmeticException
public class ExceptionHandlingExample {
public static void main(String[] args) {
int a = 10, b = 0;
try {
int result = a / b; // Throws ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero: " + e.getMessage());
} finally {
System.out.println("This always executes.");
}
}
}
Output:
Cannot divide by zero: / by zero
This always executes.
2. throw and throws
throw: Used to explicitly throw an exception.throws: Used in method signatures to declare exceptions that the method might throw.
Example: Custom Exception
class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Insufficient funds: " + (amount - balance));
}
balance -= amount;
System.out.println("Withdrawn: " + amount);
}
}
Real-World Example: Bank Withdrawal
Imagine a Khalti or Nabil Bank app where a user tries to withdraw more money than their balance. The app uses throw to raise an InsufficientFundsException and displays a user-friendly message like:
"Your account has only Rs. 5,000. Withdrawal failed."
3. Custom Exceptions
You can create your own exceptions by extending the Exception or RuntimeException class.
Example: InvalidAgeException
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
public class AgeValidator {
public static void validateAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age must be at least 18.");
}
System.out.println("Age is valid.");
}
}
Real-World Example: eSewa Registration
When registering for eSewa, if a user enters an age below 18, the system throws a custom InvalidAgeException and prompts:
"You must be 18 or older to register."
Multi-Catch Block
Java allows handling multiple exceptions in a single catch block using the | operator.
Example:
try {
int[] arr = new int[5];
arr[10] = 50; // ArrayIndexOutOfBoundsException
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
Nested try-catch Blocks
You can nest try-catch blocks to handle exceptions at different levels.
Example:
try {
try {
int result = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Inner catch: " + e);
throw new ArrayIndexOutOfBoundsException("Nested exception");
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Outer catch: " + e);
}
Best Practices for Exception Handling
- Catch Specific Exceptions: Avoid catching generic
Exceptionunless necessary. - Use Custom Exceptions: Improve code readability and maintainability.
- Clean Up Resources: Use
finallyortry-with-resourcesto close files, connections, etc. - Log Exceptions: Use logging frameworks (e.g.,
java.util.logging) for debugging. - Avoid Empty Catch Blocks: Always handle or log exceptions.
In the Real World
Khalti App (Nepal):
- Uses
try-catchto handle network failures when processing transactions. If the server is down, it shows:"Payment failed. Please check your internet connection."
- Custom exceptions like
InsufficientBalanceExceptionare thrown when a user tries to pay more than their available balance.
- Uses
Ncell Recharge System:
- Validates input (e.g., phone number format) using
try-catch. If invalid, it throws aInvalidInputExceptionand asks the user to re-enter details.
- Validates input (e.g., phone number format) using
Daraz Order Processing:
- Uses
try-finallyto ensure order details are saved to a database even if an error occurs during payment processing. If the payment fails, it rolls back the order and notifies the user.
- Uses
Exam Tip
- Understand the difference between checked and unchecked exceptions.
- Practice writing
try-catch-finallyblocks for common exceptions likeArithmeticException,NullPointerException, andIOException. - Know how to create custom exceptions and when to use them.
- Be familiar with
throwvs.throws:throwis used inside a method to raise an exception.throwsis used in the method signature to declare exceptions.
- Expect questions on:
- Handling multiple exceptions with multi-catch.
- Nested
try-catchblocks. - Best practices (e.g., logging, resource cleanup).
Worked Example: File Handling with Exception Handling
import java.io.*;
public class FileReaderExample {
public static void main(String[] args) {
File file = new File("example.txt");
try {
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
}
}
State After Each Step:
- File Creation:
flowchart TD A["File: example.txt"] -->|"Exists?"| B{"No"} B --> C["FileNotFoundException thrown"] - File Reading:
flowchart TD A["FileReader opened"] --> B["BufferedReader reads line"] B --> C["Line printed"] C --> D["Loop continues"] - Exception Handling:
flowchart TD A["IOException occurs"] --> B["Caught in catch block"] B --> C["Error message displayed"]
Real-World Tie-In: NTC Website
When you try to download a NTC form (e.g., vehicle registration) but the file is corrupted, the website’s backend uses try-catch to handle the IOException and displays:
"File corrupted. Please try again later."
Comparison Table: Checked vs. Unchecked Exceptions
| Feature | Checked Exception | Unchecked Exception |
|---|---|---|
| Inheritance | Extends Exception |
Extends RuntimeException |
| Handling | Must be handled (compile-time) | Optional (runtime) |
| Examples | IOException, SQLException |
NullPointerException, ArrayIndexOutOfBoundsException |
| Use Case | Recoverable errors (e.g., file not found) | Programming errors (e.g., logic flaws) |
| Performance Impact | Slightly slower (checked at compile time) | Faster (no compile-time checks) |
Summary of Key Points
- Exceptions disrupt normal program flow but can be handled gracefully.
- Use
try-catch-finallyto manage exceptions and ensure cleanup. - Custom exceptions improve code clarity and maintainability.
- Real-world applications (e.g., Khalti, Ncell) rely on exception handling for robustness.
- Always follow best practices: catch specific exceptions, log errors, and avoid empty catch blocks.
Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 6.
Discussion
Loading…