Introduction
Imagine you're a chef cooking in a kitchen. Sometimes things go wrong—you might burn the food, drop a plate, or run out of ingredients. A good chef has contingency plans: backup ingredients, fire extinguishers, and first aid kits. In Java, try-catch blocks are exactly like these contingency plans—they handle unexpected situations (exceptions) gracefully without crashing your entire program!
Try-catch blocks are Java's mechanism for exception handling. They allow you to write code that might cause errors in a "protected" zone (try block) and then handle those errors gracefully in "recovery" zones (catch blocks).
What are Try-Catch Blocks?
Try-catch blocks are control structures that handle exceptions (runtime errors) in Java. They allow you to separate normal code execution from error handling logic.
Key Characteristics:
- ✅ Try block - Code that might throw exceptions
- ✅ Catch block - Handles specific exceptions
- ✅ Finally block - Always executes (cleanup code)
- ✅ Prevents program crashes - Graceful error recovery
- ✅ Multiple catch blocks - Handle different exception types
Code Explanation with Examples
Example 1: Basic Try-Catch Structure
public class BasicTryCatch {
public static void main(String[] args) {
System.out.println("=== BASIC TRY-CATCH STRUCTURE ===");
// ❌ DANGEROUS: Code without exception handling
// int result = 10 / 0; // This would crash the program!
// ✅ SAFE: Code with exception handling
try {
System.out.println("Starting risky operation...");
int result = 10 / 0; // This will throw ArithmeticException
System.out.println("Result: " + result); // This line won't execute
} catch (ArithmeticException e) {
System.out.println("❌ Error: Cannot divide by zero!");
System.out.println("Exception message: " + e.getMessage());
}
System.out.println("Program continues normally after handling exception!");
System.out.println("\n=== SUCCESSFUL OPERATION ===");
try {
System.out.println("Starting safe operation...");
int result = 10 / 2; // This works fine
System.out.println("Result: " + result); // This line executes
} catch (ArithmeticException e) {
System.out.println("❌ Error: " + e.getMessage()); // Won't execute
}
System.out.println("Program continues after successful operation!");
System.out.println("\n=== EXCEPTION OBJECT INFORMATION ===");
try {
int[] numbers = {1, 2, 3};
System.out.println("Accessing array: " + numbers[5]); // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("❌ Array error occurred!");
System.out.println("Message: " + e.getMessage());
System.out.println("Exception type: " + e.getClass().getSimpleName());
System.out.println("Stack trace:");
e.printStackTrace(); // Shows where error occurred
}
}
}
Output:
=== BASIC TRY-CATCH STRUCTURE === Starting risky operation... ❌ Error: Cannot divide by zero! Exception message: / by zero Program continues normally after handling exception! === SUCCESSFUL OPERATION === Starting safe operation... Result: 5 Program continues after successful operation! === EXCEPTION OBJECT INFORMATION === ❌ Array error occurred! Message: Index 5 out of bounds for length 3 Exception type: ArrayIndexOutOfBoundsException Stack trace: java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3 at BasicTryCatch.main(BasicTryCatch.java:33)
Example 2: Multiple Catch Blocks
import java.util.InputMismatchException;
import java.util.Scanner;
public class MultipleCatchBlocks {
public static void main(String[] args) {
System.out.println("=== MULTIPLE CATCH BLOCKS ===");
Scanner scanner = new Scanner(System.in);
// Example 1: Different exceptions in same try block
System.out.println("\n=== EXAMPLE 1: DIVISION CALCULATOR ===");
try {
System.out.print("Enter numerator: ");
int numerator = scanner.nextInt();
System.out.print("Enter denominator: ");
int denominator = scanner.nextInt();
int result = numerator / denominator;
System.out.println("Result: " + numerator + " / " + denominator + " = " + result);
} catch (InputMismatchException e) {
System.out.println("❌ Input error: Please enter valid integers!");
scanner.nextLine(); // Clear invalid input
} catch (ArithmeticException e) {
System.out.println("❌ Math error: " + e.getMessage());
System.out.println("Cannot divide by zero!");
} catch (Exception e) {
System.out.println("❌ Unexpected error: " + e.getMessage());
}
// Example 2: Array operations with multiple exceptions
System.out.println("\n=== EXAMPLE 2: ARRAY OPERATIONS ===");
int[] numbers = {10, 20, 30, 40, 50};
try {
System.out.print("Enter array index to access: ");
int index = scanner.nextInt();
System.out.print("Enter divisor for calculation: ");
int divisor = scanner.nextInt();
int value = numbers[index];
int calculation = value / divisor;
System.out.println("Array[" + index + "] = " + value);
System.out.println(value + " / " + divisor + " = " + calculation);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("❌ Array index error: " + e.getMessage());
System.out.println("Valid indices are 0 to " + (numbers.length - 1));
} catch (InputMismatchException e) {
System.out.println("❌ Input error: Please enter a valid integer!");
scanner.nextLine(); // Clear invalid input
} catch (ArithmeticException e) {
System.out.println("❌ Math error: " + e.getMessage());
} catch (Exception e) {
System.out.println("❌ Unexpected error occurred!");
e.printStackTrace();
}
// Example 3: Order matters - specific to general
System.out.println("\n=== EXAMPLE 3: CATCH BLOCK ORDER ===");
try {
String text = null;
System.out.println("Text length: " + text.length()); // NullPointerException
} catch (NullPointerException e) {
System.out.println("✅ Caught specific exception: NullPointerException");
System.out.println("Message: " + e.getMessage());
} catch (Exception e) {
System.out.println("✅ Caught general exception");
System.out.println("This would catch any other exception");
}
// ❌ BAD: Wrong order (general before specific)
/*
try {
// some code
} catch (Exception e) { // ❌ Too general - catches everything
System.out.println("General exception");
} catch (NullPointerException e) { // ❌ Unreachable - compiler error!
System.out.println("This will never be executed");
}
*/
scanner.close();
System.out.println("\n=== PROGRAM COMPLETED SUCCESSFULLY ===");
}
public static void demonstrateCatchOrder() {
System.out.println("\n=== PROPER CATCH ORDER ===");
System.out.println("Specific exceptions first, then general ones:");
System.out.println("try {");
System.out.println(" // risky code");
System.out.println("} catch (SpecificException e) {");
System.out.println(" // handle specific case");
System.out.println("} catch (AnotherSpecificException e) {");
System.out.println(" // handle another specific case");
System.out.println("} catch (Exception e) {");
System.out.println(" // handle any other exceptions");
System.out.println("}");
}
}
Output:
=== MULTIPLE CATCH BLOCKS === === EXAMPLE 1: DIVISION CALCULATOR === Enter numerator: abc ❌ Input error: Please enter valid integers! === EXAMPLE 2: ARRAY OPERATIONS === Enter array index to access: 10 ❌ Array index error: Index 10 out of bounds for length 5 Valid indices are 0 to 4 === EXAMPLE 3: CATCH BLOCK ORDER === ✅ Caught specific exception: NullPointerException Message: null === PROGRAM COMPLETED SUCCESSFULLY ===
Example 3: Finally Block and Try-With-Resources
import java.io.*;
import java.util.Scanner;
public class FinallyAndResources {
// Method demonstrating finally block
public static void readFileWithFinally(String filename) {
FileReader reader = null;
System.out.println("\n=== READING FILE WITH FINALLY BLOCK: " + filename + " ===");
try {
reader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
System.out.println("File contents:");
while ((line = bufferedReader.readLine()) != null) {
System.out.println(" " + line);
}
System.out.println("✅ File read successfully!");
} catch (FileNotFoundException e) {
System.out.println("❌ File error: " + e.getMessage());
System.out.println("Please check if the file exists!");
} catch (IOException e) {
System.out.println("❌ Reading error: " + e.getMessage());
} finally {
// ❌ IMPORTANT: Finally block ALWAYS executes
System.out.println("🔒 Finally block executed - cleaning up resources");
if (reader != null) {
try {
reader.close();
System.out.println("✅ File reader closed successfully");
} catch (IOException e) {
System.out.println("❌ Error closing file: " + e.getMessage());
}
}
}
}
// Method demonstrating try-with-resources (Java 7+)
public static void readFileWithResources(String filename) {
System.out.println("\n=== READING FILE WITH TRY-WITH-RESOURCES: " + filename + " ===");
// ✅ try-with-resources automatically closes resources
try (FileReader reader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(reader)) {
System.out.println("File contents:");
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(" " + line);
}
System.out.println("✅ File read successfully!");
} catch (FileNotFoundException e) {
System.out.println("❌ File error: " + e.getMessage());
} catch (IOException e) {
System.out.println("❌ Reading error: " + e.getMessage());
}
// No finally block needed - resources automatically closed!
}
// Method demonstrating finally block behavior
public static void demonstrateFinallyBehavior() {
System.out.println("\n=== FINALLY BLOCK BEHAVIOR ===");
// Case 1: No exception
System.out.println("Case 1: No exception");
try {
System.out.println(" Try block executed");
} catch (Exception e) {
System.out.println(" Catch block executed");
} finally {
System.out.println(" ✅ Finally block executed");
}
// Case 2: Exception caught
System.out.println("\nCase 2: Exception caught");
try {
System.out.println(" Try block executed");
throw new RuntimeException("Test exception");
} catch (Exception e) {
System.out.println(" ✅ Catch block executed: " + e.getMessage());
} finally {
System.out.println(" ✅ Finally block executed");
}
// Case 3: Exception not caught
System.out.println("\nCase 3: Exception not caught (different type)");
try {
System.out.println(" Try block executed");
throw new RuntimeException("Uncaught exception");
} catch (NullPointerException e) { // Wrong exception type
System.out.println(" Catch block executed");
} finally {
System.out.println(" ✅ Finally block executed even with uncaught exception!");
}
// Case 4: Return in try block
System.out.println("\nCase 4: Return statement in try block");
String result = testReturnInTry();
System.out.println(" Method returned: " + result);
}
public static String testReturnInTry() {
try {
System.out.println(" Try block with return statement");
return "Return value from try";
} catch (Exception e) {
System.out.println(" Catch block executed");
return "Return value from catch";
} finally {
System.out.println(" ✅ Finally block executed after return!");
// Note: You can't change the return value in finally
}
}
// Custom resource that implements AutoCloseable
static class DatabaseConnection implements AutoCloseable {
private String connectionId;
public DatabaseConnection(String id) {
this.connectionId = id;
System.out.println("🔗 Database connection opened: " + connectionId);
}
public void executeQuery(String query) {
System.out.println("📊 Executing query on " + connectionId + ": " + query);
}
@Override
public void close() {
System.out.println("🔒 Database connection closed: " + connectionId);
}
}
public static void demonstrateAutoCloseable() {
System.out.println("\n=== AUTOCLOSEABLE RESOURCES ===");
// Using custom AutoCloseable resource
try (DatabaseConnection db = new DatabaseConnection("DB-001")) {
db.executeQuery("SELECT * FROM users");
db.executeQuery("UPDATE settings SET value = 'new'");
// No need to manually close - automatically called
} catch (Exception e) {
System.out.println("❌ Database error: " + e.getMessage());
}
// Resources automatically closed even if exception occurs
System.out.println("Program continues after database operations");
}
public static void main(String[] args) {
System.out.println("=== FINALLY BLOCK AND TRY-WITH-RESOURCES ===");
// Create a test file first
createTestFile("test.txt");
// Demonstrate finally block
readFileWithFinally("test.txt");
readFileWithFinally("nonexistent.txt"); // This will cause error
// Demonstrate try-with-resources
readFileWithResources("test.txt");
readFileWithResources("nonexistent.txt"); // This will cause error
// Demonstrate finally behavior
demonstrateFinallyBehavior();
// Demonstrate AutoCloseable
demonstrateAutoCloseable();
// Clean up
deleteTestFile("test.txt");
}
private static void createTestFile(String filename) {
try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
writer.println("Hello World!");
writer.println("This is a test file.");
writer.println("Java Exception Handling Demo");
} catch (IOException e) {
System.out.println("Error creating test file: " + e.getMessage());
}
}
private static void deleteTestFile(String filename) {
File file = new File(filename);
if (file.exists()) {
file.delete();
}
}
}
Output:
=== FINALLY BLOCK AND TRY-WITH-RESOURCES === === READING FILE WITH FINALLY BLOCK: test.txt === File contents: Hello World! This is a test file. Java Exception Handling Demo ✅ File read successfully! 🔒 Finally block executed - cleaning up resources ✅ File reader closed successfully === READING FILE WITH FINALLY BLOCK: nonexistent.txt === ❌ File error: nonexistent.txt (No such file or directory) Please check if the file exists! 🔒 Finally block executed - cleaning up resources === READING FILE WITH TRY-WITH-RESOURCES: test.txt === File contents: Hello World! This is a test file. Java Exception Handling Demo ✅ File read successfully! === READING FILE WITH TRY-WITH-RESOURCES: nonexistent.txt === ❌ File error: nonexistent.txt (No such file or directory) === FINALLY BLOCK BEHAVIOR === Case 1: No exception Try block executed ✅ Finally block executed Case 2: Exception caught Try block executed ✅ Catch block executed: Test exception ✅ Finally block executed Case 3: Exception not caught (different type) Try block executed ✅ Finally block executed even with uncaught exception! Case 4: Return statement in try block Try block with return statement ✅ Finally block executed after return! Method returned: Return value from try === AUTOCLOSEABLE RESOURCES === 🔗 Database connection opened: DB-001 📊 Executing query on DB-001: SELECT * FROM users 📊 Executing query on DB-001: UPDATE settings SET value = 'new' 🔒 Database connection closed: DB-001 Program continues after database operations
Example 4: Real-World Exception Handling Scenarios
import java.net.URL;
import java.net.MalformedURLException;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class RealWorldScenarios {
// Scenario 1: User input validation
public static void validateUserRegistration(String username, String email, String ageStr) {
System.out.println("\n=== USER REGISTRATION VALIDATION ===");
System.out.println("Username: " + username);
System.out.println("Email: " + email);
System.out.println("Age: " + ageStr);
try {
// Validate username
if (username == null || username.trim().isEmpty()) {
throw new IllegalArgumentException("Username cannot be empty");
}
if (username.length() < 3) {
throw new IllegalArgumentException("Username must be at least 3 characters");
}
// Validate email using regex
validateEmail(email);
// Validate age
int age = Integer.parseInt(ageStr);
if (age < 13 || age > 120) {
throw new IllegalArgumentException("Age must be between 13 and 120");
}
System.out.println("✅ Registration successful! Welcome, " + username);
} catch (IllegalArgumentException e) {
System.out.println("❌ Validation error: " + e.getMessage());
} catch (NumberFormatException e) {
System.out.println("❌ Age error: Please enter a valid number for age");
} catch (Exception e) {
System.out.println("❌ Unexpected error during registration: " + e.getMessage());
}
}
private static void validateEmail(String email) {
if (email == null || !email.contains("@")) {
throw new IllegalArgumentException("Invalid email format");
}
// Simple email validation
String emailRegex = "^[A-Za-z0-9+_.-]+@(.+)$";
if (!Pattern.matches(emailRegex, email)) {
throw new IllegalArgumentException("Email format is invalid");
}
}
// Scenario 2: Network operations
public static void checkWebsiteAvailability(String urlString) {
System.out.println("\n=== WEBSITE AVAILABILITY CHECK ===");
System.out.println("Checking: " + urlString);
try {
URL url = new URL(urlString);
// Simulate network check (in real app, you'd use HttpURLConnection)
if (urlString.contains("example.com")) {
System.out.println("✅ Website is available and responding");
} else if (urlString.contains("unavailable")) {
throw new RuntimeException("Connection timeout - website not responding");
} else {
throw new RuntimeException("HTTP 404 - Website not found");
}
} catch (MalformedURLException e) {
System.out.println("❌ URL error: Invalid URL format");
System.out.println("Please check the website address");
} catch (RuntimeException e) {
System.out.println("❌ Network error: " + e.getMessage());
} catch (Exception e) {
System.out.println("❌ Unexpected network error: " + e.getMessage());
}
}
// Scenario 3: Database operations
public static void processDatabaseTransaction(String operation, String data) {
System.out.println("\n=== DATABASE TRANSACTION ===");
System.out.println("Operation: " + operation);
System.out.println("Data: " + data);
try {
// Simulate database connection
if (!connectToDatabase()) {
throw new RuntimeException("Cannot connect to database server");
}
// Simulate different database operations
switch (operation.toUpperCase()) {
case "INSERT":
if (data == null || data.isEmpty()) {
throw new IllegalArgumentException("Insert data cannot be empty");
}
System.out.println("✅ Data inserted successfully");
break;
case "UPDATE":
if (data.contains("invalid")) {
throw new RuntimeException("Update failed - invalid data format");
}
System.out.println("✅ Data updated successfully");
break;
case "DELETE":
if (data.equals("protected")) {
throw new SecurityException("Cannot delete protected record");
}
System.out.println("✅ Data deleted successfully");
break;
default:
throw new IllegalArgumentException("Unknown operation: " + operation);
}
// Commit transaction
commitTransaction();
} catch (SecurityException e) {
System.out.println("❌ Security violation: " + e.getMessage());
rollbackTransaction();
} catch (IllegalArgumentException e) {
System.out.println("❌ Input error: " + e.getMessage());
rollbackTransaction();
} catch (RuntimeException e) {
System.out.println("❌ Database error: " + e.getMessage());
rollbackTransaction();
} catch (Exception e) {
System.out.println("❌ Unexpected database error: " + e.getMessage());
rollbackTransaction();
} finally {
closeDatabaseConnection();
}
}
private static boolean connectToDatabase() {
System.out.println("🔗 Connecting to database...");
return true; // Simulate successful connection
}
private static void commitTransaction() {
System.out.println("💾 Committing transaction...");
}
private static void rollbackTransaction() {
System.out.println("↩️ Rolling back transaction...");
}
private static void closeDatabaseConnection() {
System.out.println("🔒 Closing database connection...");
}
// Scenario 4: File processing with detailed error handling
public static void processDataFile(String filename) {
System.out.println("\n=== DATA FILE PROCESSING ===");
System.out.println("Processing file: " + filename);
try {
if (filename == null) {
throw new IllegalArgumentException("Filename cannot be null");
}
if (!filename.endsWith(".csv") && !filename.endsWith(".txt")) {
throw new IllegalArgumentException("Only CSV and TXT files are supported");
}
// Simulate file processing
String[] lines = simulateFileReading(filename);
int processedCount = 0;
for (int i = 0; i < lines.length; i++) {
try {
processDataLine(lines[i], i + 1);
processedCount++;
} catch (DataProcessingException e) {
System.out.println("⚠️ Skipping line " + (i + 1) + ": " + e.getMessage());
// Continue processing other lines
}
}
System.out.println("✅ File processing completed");
System.out.println("Successfully processed: " + processedCount + " lines");
System.out.println("Failed: " + (lines.length - processedCount) + " lines");
} catch (IllegalArgumentException e) {
System.out.println("❌ Configuration error: " + e.getMessage());
} catch (SecurityException e) {
System.out.println("❌ Access denied: " + e.getMessage());
} catch (Exception e) {
System.out.println("❌ File processing failed: " + e.getMessage());
}
}
private static String[] simulateFileReading(String filename) {
if (filename.contains("corrupt")) {
throw new RuntimeException("File is corrupt or unreadable");
}
if (filename.contains("large")) {
throw new RuntimeException("File too large to process");
}
return new String[]{"valid data", "invalid format", "valid data", "missing fields"};
}
private static void processDataLine(String line, int lineNumber) throws DataProcessingException {
if (line.contains("invalid") || line.contains("missing")) {
throw new DataProcessingException("Invalid data format in line " + lineNumber);
}
System.out.println("✅ Processed line " + lineNumber + ": " + line);
}
// Custom exception for business logic
static class DataProcessingException extends Exception {
public DataProcessingException(String message) {
super(message);
}
}
// Scenario 5: Retry mechanism with exception handling
public static void executeWithRetry(Runnable operation, int maxRetries) {
System.out.println("\n=== OPERATION WITH RETRY MECHANISM ===");
System.out.println("Max retries: " + maxRetries);
int attempt = 1;
while (attempt <= maxRetries) {
try {
System.out.println("Attempt " + attempt + "...");
operation.run();
System.out.println("✅ Operation completed successfully on attempt " + attempt);
return; // Success - exit method
} catch (RuntimeException e) {
System.out.println("❌ Attempt " + attempt + " failed: " + e.getMessage());
if (attempt == maxRetries) {
System.out.println("💥 All retry attempts exhausted. Operation failed.");
throw e; // Re-throw after final attempt
}
// Wait before retry (exponential backoff)
try {
long waitTime = Math.min(1000 * (long) Math.pow(2, attempt - 1), 10000);
System.out.println("⏳ Waiting " + waitTime + "ms before retry...");
Thread.sleep(waitTime);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Operation interrupted", ie);
}
attempt++;
}
}
}
public static void main(String[] args) {
System.out.println("=== REAL-WORLD EXCEPTION HANDLING SCENARIOS ===");
// Scenario 1: User registration
validateUserRegistration("john_doe", "[email protected]", "25");
validateUserRegistration("jo", "invalid-email", "not-a-number");
validateUserRegistration("", "[email protected]", "150");
// Scenario 2: Network operations
checkWebsiteAvailability("https://example.com");
checkWebsiteAvailability("invalid-url");
checkWebsiteAvailability("https://unavailable-site.com");
// Scenario 3: Database operations
processDatabaseTransaction("INSERT", "user data");
processDatabaseTransaction("UPDATE", "invalid data");
processDatabaseTransaction("DELETE", "protected");
processDatabaseTransaction("UNKNOWN", "data");
// Scenario 4: File processing
processDataFile("data.csv");
processDataFile("corrupt.csv");
processDataFile("huge_data.csv");
// Scenario 5: Retry mechanism
executeWithRetry(() -> {
// Simulate flaky operation
if (Math.random() < 0.7) {
throw new RuntimeException("Temporary network failure");
}
System.out.println("📡 Network operation successful!");
}, 3);
System.out.println("\n=== ALL SCENARIOS COMPLETED ===");
}
}
Output:
=== REAL-WORLD EXCEPTION HANDLING SCENARIOS === === USER REGISTRATION VALIDATION === Username: john_doe Email: [email protected] Age: 25 ✅ Registration successful! Welcome, john_doe === USER REGISTRATION VALIDATION === Username: jo Email: invalid-email Age: not-a-number ❌ Validation error: Username must be at least 3 characters === USER REGISTRATION VALIDATION === Username: Email: [email protected] Age: 150 ❌ Validation error: Username cannot be empty === WEBSITE AVAILABILITY CHECK === Checking: https://example.com ✅ Website is available and responding === WEBSITE AVAILABILITY CHECK === Checking: invalid-url ❌ URL error: Invalid URL format Please check the website address === WEBSITE AVAILABILITY CHECK === Checking: https://unavailable-site.com ❌ Network error: Connection timeout - website not responding === DATABASE TRANSACTION === Operation: INSERT Data: user data 🔗 Connecting to database... ✅ Data inserted successfully 💾 Committing transaction... 🔒 Closing database connection... === DATABASE TRANSACTION === Operation: UPDATE Data: invalid data 🔗 Connecting to database... ❌ Database error: Update failed - invalid data format ↩️ Rolling back transaction... 🔒 Closing database connection... === DATABASE TRANSACTION === Operation: DELETE Data: protected 🔗 Connecting to database... ❌ Security violation: Cannot delete protected record ↩️ Rolling back transaction... 🔒 Closing database connection... === DATABASE TRANSACTION === Operation: UNKNOWN Data: data 🔗 Connecting to database... ❌ Input error: Unknown operation: UNKNOWN ↩️ Rolling back transaction... 🔒 Closing database connection... === DATA FILE PROCESSING === Processing file: data.csv ✅ Processed line 1: valid data ⚠️ Skipping line 2: Invalid data format in line 2 ✅ Processed line 3: valid data ⚠️ Skipping line 4: Invalid data format in line 4 ✅ File processing completed Successfully processed: 2 lines Failed: 2 lines === DATA FILE PROCESSING === Processing file: corrupt.csv ❌ File processing failed: File is corrupt or unreadable === DATA FILE PROCESSING === Processing file: huge_data.csv ❌ File processing failed: File too large to process === OPERATION WITH RETRY MECHANISM === Max retries: 3 Attempt 1... ❌ Attempt 1 failed: Temporary network failure ⏳ Waiting 1000ms before retry... Attempt 2... ❌ Attempt 2 failed: Temporary network failure ⏳ Waiting 2000ms before retry... Attempt 3... 📡 Network operation successful! ✅ Operation completed successfully on attempt 3 === ALL SCENARIOS COMPLETED ===
Example 5: Best Practices and Common Patterns
```java
import java.util.logging.*;
public class BestPractices {
private static final Logger logger = Logger.getLogger(BestPractices.class.getName());
// ✅ BEST PRACTICE 1: Use specific exceptions
public static void specificVsGeneral() {
System.out.println("=== SPECIFIC VS GENERAL EXCEPTIONS ===");
// ❌ BAD: Too general
try {
int[] arr = {1, 2, 3};
System.out.println(arr[5]);
} catch (Exception e) { // ❌ Catches everything
System.out.println("❌ Error occurred");
}
// ✅ GOOD: Specific exceptions
try {
int[] arr = {1, 2, 3};
System.out.println(arr[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("✅ Specific: Array index out of bounds");
} catch (NullPointerException e) {
System.out.println("✅ Specific: Null pointer exception");
}
}
// ✅ BEST PRACTICE 2: Don't ignore exceptions
public static void dontIgnoreExceptions() {
System.out.println("\n=== DON'T IGNORE EXCEPTIONS ===");
// ❌ BAD: Ignoring exception (empty catch block)
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
// ❌ Empty - exception completely ignored!
}
// ✅ GOOD: Handle or log the exception
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("✅ Handled: " + e.getMessage());
logger.warning("Division by zero attempted: " + e.getMessage());
}
}
// ✅ BEST PRACTICE 3: Use try-with-resources
public static void useTryWithResources() {
System.out.println("\n=== USE TRY-WITH-RESOURCES ===");
// ❌ BAD: Manual resource management
/*
FileInputStream fis = null;
try {
fis = new FileInputStream("file.txt");
// use stream
} catch (IOException e) {
// handle
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// ignore
}
}
}
*/
// ✅ GOOD: Try-with-resources
/*
try (FileInputStream fis = new FileInputStream("file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
// use resources
} catch (IOException e) {
// handle exception
}
// Resources automatically closed
*/
System.out.println("✅ Use try-with-resources for automatic cleanup");
}
// ✅ BEST PRACTICE 4: Provide useful error messages
public static void usefulErrorMessages() {
System.out.println("\n=== USEFUL ERROR MESSAGES ===");
// ❌ BAD: Vague error message
try {
String data = null;
data.length();
} catch (Exception e) {
System.out.println("❌ Error occurred"); // Not helpful
}
// ✅ GOOD: Descriptive error message
try {
String data = null;
data.length();
} catch (NullPointerException e) {
System.out.println("✅ Error: Attempted to call method on null object");
System.out.println(" Context: While processing user data");
System.out.println(" Action: Please check if data is properly initialized");
}
}
// ✅ BEST PRACTICE 5: Use custom exceptions for business logic
public static void useCustomExceptions() {
System.out.println("\n=== CUSTOM EXCEPTIONS ===");
try {
processOrder(-1); // Invalid order ID
} catch (InvalidOrderException e) {
System.out.println("✅ Custom exception caught: " + e.getMessage());
System.out.println(" Error code: " + e.getErrorCode());
}
try {
processOrder(1000); // Non-existent order
} catch (InvalidOrderException e) {
System.out.println("✅ Custom exception caught: " + e.getMessage());
System.out.println(" Error code: " + e.getErrorCode());
}
}
private static void processOrder(int orderId) throws InvalidOrderException {
if (orderId <= 0) {
throw new InvalidOrderException("Order ID must be positive", "ERR_001");
}
if (orderId > 100) {
throw new InvalidOrderException("Order not found", "ERR_002");
}
System.out.println("✅ Processing order: " + orderId);
}
// Custom exception class
static class InvalidOrderException extends Exception {
private final String errorCode;
public InvalidOrderException(String message, String errorCode) {
super(message);
this.errorCode = errorCode;
}
public String getErrorCode() {
return errorCode;
}
}
// ✅ BEST PRACTICE 6: Exception translation
public static void exceptionTranslation() {
System.out.println("\n=== EXCEPTION TRANSLATION ===");
try {
readConfigurationFile();
} catch (ConfigurationException e) {
System.out.println("✅ Translated exception: " + e.getMessage());
System.out.println(" Original cause: " + e.getCause().getMessage());
}
}
private static void readConfigurationFile() throws ConfigurationException {
try {
// Simulate low-level IO operation
throw new java.io.FileNotFoundException("config.properties not found");
} catch (java.io.IOException e) {
// Translate to business-level exception
throw new ConfigurationException("Failed to read configuration", e);
}
}
static class ConfigurationException extends Exception {
public ConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}
// ✅ BEST PRACTICE 7: Use finally for cleanup, not business logic
public static void properFinallyUsage() {
System.out.println("\n=== PROPER FINALLY USAGE ===");
// ❌ BAD: Business logic in finally
/*
try {
// some operation
} finally {
if (success) { // ❌ Don't put conditions in finally
commitTransaction();
}
}
*/
// ✅ GOOD: Cleanup only in finally
boolean success = false;
try {
System.out.println("Performing operation...");
success = true; // Operation successful