This module introduces exception handling in Java, focusing on try-catch blocks, throwing exceptions, creating custom exceptions, and using the finally block. Designed for beginners building on Weeks 1-8 of the 3-month Java fundamentals plan, it includes detailed explanations, multiple code examples per concept, and practice exercises for each day of Week 9. The module concludes with a console-based File Processing System mini-project to apply these concepts.
Objective: Learn to handle exceptions using try-catch blocks.
- Exception: An error or unexpected event during program execution (e.g., division by zero, accessing invalid array index).
- try-catch: Used to catch and handle exceptions to prevent program crashes.
- Syntax:
try { // Code that might throw an exception } catch (ExceptionType e) { // Handle the exception }
- Syntax:
- Common exceptions:
ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException. - Use
e.getMessage()ore.printStackTrace()for debugging.
Example 1: Handling Division by Zero
public class DivisionExample {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero");
}
}
}Example 2: Array Index Error
public class ArrayIndexExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
try {
System.out.println(numbers[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Invalid index");
}
}
}Example 3: Multiple Catch Blocks
public class MultipleCatchExample {
public static void main(String[] args) {
int[] arr = {1, 2};
try {
int result = arr[0] / arr[2];
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Arithmetic Error: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index Error: " + e.getMessage());
}
}
}- Write a program to divide two numbers and handle division by zero.
- Create an array and attempt to access an invalid index; handle the exception.
- Write a program that handles both
ArithmeticExceptionandArrayIndexOutOfBoundsException.
Practice Code:
public class TryCatchPractice {
public static void main(String[] args) {
try {
int[] numbers = {10, 20};
int result = numbers[0] / 0;
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Invalid array index");
}
}
}Objective: Learn to throw exceptions using throw and throws.
- throw: Explicitly throws an exception.
- Syntax:
throw new ExceptionType("message");
- Syntax:
- throws: Declares that a method might throw an exception.
- Syntax:
returnType methodName() throws ExceptionType { // code }
- Syntax:
- Common use: Validate inputs and throw exceptions for invalid cases.
Example 1: Throwing an Exception
public class ThrowExample {
public static void main(String[] args) {
try {
checkAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or older");
}
System.out.println("Age is valid: " + age);
}
}Example 2: Using throws
public class ThrowsExample {
public static void main(String[] args) {
try {
divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
}
}
static int divide(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("Division by zero");
}
return a / b;
}
}Example 3: Validating Input
public class InputValidationExample {
public static void main(String[] args) {
try {
setScore(-10);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void setScore(int score) {
if (score < 0 || score > 100) {
throw new IllegalArgumentException("Score must be between 0 and 100");
}
System.out.println("Score set: " + score);
}
}- Write a method to validate a positive number; throw
IllegalArgumentExceptionif negative. - Create a method that throws an
ArithmeticExceptionfor division by zero. - Write a program to validate a string length (must be > 0) and throw an exception if invalid.
Practice Code:
public class ThrowPractice {
public static void main(String[] args) {
try {
validateString("");
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void validateString(String str) {
if (str.isEmpty()) {
throw new IllegalArgumentException("String cannot be empty");
}
System.out.println("Valid string: " + str);
}
}Objective: Create and use custom exception classes.
- Custom Exception: A user-defined exception class, typically extending
ExceptionorRuntimeException. - Syntax:
class CustomException extends Exception { public CustomException(String message) { super(message); } }
- Use for specific error scenarios in your application.
Example 1: Basic Custom Exception
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void main(String[] args) {
try {
checkAge(12);
} catch (InvalidAgeException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age must be 18 or older");
}
System.out.println("Age is valid");
}
}Example 2: Custom Exception with Validation
class InvalidScoreException extends Exception {
public InvalidScoreException(String message) {
super(message);
}
}
public class ScoreValidationExample {
public static void main(String[] args) {
try {
setScore(150);
} catch (InvalidScoreException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void setScore(int score) throws InvalidScoreException {
if (score < 0 || score > 100) {
throw new InvalidScoreException("Score must be between 0 and 100");
}
System.out.println("Score set: " + score);
}
}Example 3: Custom Exception in Method
class InvalidNameException extends Exception {
public InvalidNameException(String message) {
super(message);
}
}
public class NameValidationExample {
public static void main(String[] args) {
try {
validateName("");
} catch (InvalidNameException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void validateName(String name) throws InvalidNameException {
if (name == null || name.isEmpty()) {
throw new InvalidNameException("Name cannot be empty or null");
}
System.out.println("Valid name: " + name);
}
}- Create a custom
InvalidGradeExceptionand use it to validate grades (0-100). - Write a method that throws a custom exception for negative numbers.
- Create a program to validate a username (non-empty) using a custom exception.
Practice Code:
class InvalidGradeException extends Exception {
public InvalidGradeException(String message) {
super(message);
}
}
public class CustomExceptionPractice {
public static void main(String[] args) {
try {
addGrade(120);
} catch (InvalidGradeException e) {
System.out.println("Error: " + e.getMessage());
}
}
static void addGrade(double grade) throws InvalidGradeException {
if (grade < 0 || grade > 100) {
throw new InvalidGradeException("Grade must be between 0 and 100");
}
System.out.println("Grade added: " + grade);
}
}Objective: Use the finally block for cleanup tasks.
- finally: A block that always executes, regardless of whether an exception is thrown or caught.
- Syntax:
try { // Code } catch (ExceptionType e) { // Handle exception } finally { // Cleanup code }
- Common use: Closing resources (e.g., files, connections).
Example 1: Basic Finally Block
public class FinallyExample {
public static void main(String[] args) {
try {
int result = 10 / 2;
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("This always runs");
}
}
}Example 2: Finally with Exception
public class FinallyExceptionExample {
public static void main(String[] args) {
try {
int[] arr = {1};
System.out.println(arr[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Invalid index");
} finally {
System.out.println("Cleanup complete");
}
}
}Example 3: Resource Cleanup Simulation
public class ResourceCleanupExample {
public static void main(String[] args) {
try {
System.out.println("Opening resource");
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("Closing resource");
}
}
}- Write a program with a
try-catch-finallyblock to handle division by zero. - Create a program to access an array index and use
finallyfor cleanup. - Simulate opening and closing a resource (e.g., print "Resource closed" in
finally).
Practice Code:
public class FinallyPractice {
public static void main(String[] args) {
try {
int[] arr = {1, 2};
System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: Invalid index");
} finally {
System.out.println("Cleanup done");
}
}
}Objective: Solidify exception handling and design robust error handling.
- Review best practices:
- Use specific exception types in
catchblocks. - Throw custom exceptions for application-specific errors.
- Use
finallyfor cleanup. - Avoid catching generic
Exceptionunless necessary.
- Use specific exception types in
- Combine with Weeks 1-8 concepts (OOP, collections, loops).
Example 1: Specific Exception Handling
public class SpecificExceptionExample {
public static void main(String[] args) {
try {
int[] arr = {1};
System.out.println(arr[0] / arr[1]);
} catch (ArithmeticException e) {
System.out.println("Arithmetic Error: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index Error: " + e.getMessage());
} finally {
System.out.println("Done");
}
}
}Example 2: Custom Exception in Class
class InvalidBalanceException extends Exception {
public InvalidBalanceException(String message) {
super(message);
}
}
public class AccountExample {
private double balance;
void deposit(double amount) throws InvalidBalanceException {
if (amount <= 0) {
throw new InvalidBalanceException("Amount must be positive");
}
balance += amount;
System.out.println("Deposited: $" + amount);
}
public static void main(String[] args) {
AccountExample account = new AccountExample();
try {
account.deposit(-50);
} catch (InvalidBalanceException e) {
System.out.println("Error: " + e.getMessage());
}
}
}Example 3: Combining Collections and Exceptions
import java.util.ArrayList;
public class CollectionExceptionExample {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
try {
System.out.println(numbers.get(5));
} catch (IndexOutOfBoundsException e) {
System.out.println("Error: Invalid index");
} finally {
System.out.println("List access complete");
}
}
}- Write a method to validate an array index and throw a custom exception if invalid.
- Create a program with a
try-catch-finallyblock to handle a collection access error. - Combine a
HashMapwith exception handling to validate key existence.
Practice Code:
import java.util.HashMap;
public class ExceptionReviewPractice {
public static void main(String[] args) {
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 85);
try {
getScore(scores, "Bob");
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("Operation complete");
}
}
static int getScore(HashMap<String, Integer> scores, String name) {
if (!scores.containsKey(name)) {
throw new IllegalArgumentException("Student not found: " + name);
}
return scores.get(name);
}
}Objective: Consolidate Week 9 learning with a File Processing System.
- Revisit:
try-catchfor handling exceptions.throwandthrowsfor custom error handling.- Custom exceptions for specific scenarios.
finallyfor cleanup.
- Debug common errors (e.g., unhandled exceptions, missing
finallycleanup).
Create a console-based program that simulates file processing:
- Defines a
Fileclass with fieldsnameandsize(in KB). - Uses a
HashMapto store files (name as key,Fileobject as value). - Includes methods to add a file, access a file, and validate size.
- Uses custom exceptions for invalid file names or sizes.
- Uses
try-catch-finallyto handle operations and simulate cleanup.
Project Code:
import java.util.HashMap;
class InvalidFileException extends Exception {
public InvalidFileException(String message) {
super(message);
}
}
public class FileProcessingSystem {
private HashMap<String, File> files;
FileProcessingSystem() {
files = new HashMap<>();
}
void addFile(String name, double size) throws InvalidFileException {
try {
if (name == null || name.isEmpty()) {
throw new InvalidFileException("File name cannot be empty");
}
if (size <= 0) {
throw new InvalidFileException("File size must be positive");
}
files.put(name, new File(name, size));
System.out.println("Added file: " + name);
} finally {
System.out.println("File operation complete");
}
}
void accessFile(String name) throws InvalidFileException {
try {
if (!files.containsKey(name)) {
throw new InvalidFileException("File not found: " + name);
}
files.get(name).displayDetails();
} finally {
System.out.println("Access operation complete");
}
}
public static void main(String[] args) {
FileProcessingSystem system = new FileProcessingSystem();
try {
system.addFile("doc.txt", 100);
system.addFile("", 50); // Invalid
system.accessFile("doc.txt");
system.accessFile("image.jpg"); // Invalid
} catch (InvalidFileException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
class File {
private String name;
private double size;
File(String name, double size) {
this.name = name;
this.size = size;
}
void displayDetails() {
System.out.println("File: " + name + ", Size: " + size + " KB");
}
}- Run and test the system with different files and invalid inputs.
- Add a method to calculate the total size of all files.
- Extend the program to handle
NullPointerExceptionfor null inputs.
Extended Practice Code (with total size):
import java.util.HashMap;
class InvalidFileException extends Exception {
public InvalidFileException(String message) {
super(message);
}
}
public class ExtendedFileProcessingSystem {
private HashMap<String, File> files;
ExtendedFileProcessingSystem() {
files = new HashMap<>();
}
void addFile(String name, double size) throws InvalidFileException {
try {
if (name == null || name.isEmpty()) {
throw new InvalidFileException("File name cannot be empty");
}
files.put(name, new File(name, size));
} finally {
System.out.println("Add operation complete");
}
}
double getTotalSize() {
double total = 0;
for (File file : files.values()) {
total += file.getSize();
}
return total;
}
public static void main(String[] args) {
ExtendedFileProcessingSystem system = new ExtendedFileProcessingSystem();
try {
system.addFile("doc.txt", 100);
System.out.println("Total Size: " + system.getTotalSize() + " KB");
} catch (InvalidFileException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
class File {
private String name;
private double size;
File(String name, double size) {
this.name = name;
this.size = size;
}
double getSize() {
return size;
}
}- Practice: Test each code example in an IDE or terminal.
- Debug: Check for unhandled exceptions or missing
finallyblocks. - Resources: Refer to Oracle’s Java Tutorials or W3Schools for exception handling details.
- Experiment: Modify exception messages or add validation to see effects.