Java Errors & Exceptions

Handling runtime problems in Java programs

🚨 What are Exceptions?

Exceptions are runtime errors that occur during program execution. Java provides try-catch blocks to handle these errors gracefully and prevent program crashes.


// Basic exception handling
try {
    int result = 10 / 0; // This will cause an exception
} catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero!");
}
                                    

Common Exception Types

ArithmeticException

Division by zero errors

int result = 10 / 0;
// Throws ArithmeticException
🔍

NullPointerException

Using null object references

String text = null;
int length = text.length();
// Throws NullPointerException
📊

ArrayIndexOutOfBoundsException

Invalid array index access

int[] numbers = {1, 2, 3};
int value = numbers[5];
// Throws ArrayIndexOutOfBoundsException
🔢

NumberFormatException

Invalid string to number conversion

int number = Integer.parseInt("abc");
// Throws NumberFormatException

🔹 Try-Catch Basics

Handling exceptions with try-catch blocks:

import java.util.Scanner;

public class BasicExceptionHandling {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Enter first number: ");
        int num1 = scanner.nextInt();
        
        System.out.print("Enter second number: ");
        int num2 = scanner.nextInt();
        
        try {
            // This might throw an ArithmeticException
            int result = num1 / num2;
            System.out.println("Result: " + num1 + " / " + num2 + " = " + result);
            
        } catch (ArithmeticException e) {
            System.out.println("Error: Cannot divide by zero!");
            System.out.println("Please enter a non-zero second number.");
            
        } finally {
            // This block always executes
            System.out.println("Calculation attempt completed.");
            scanner.close();
        }
        
        System.out.println("Program continues...");
    }
}

Sample Output (Division by Zero):

Enter first number: 10
Enter second number: 0
Error: Cannot divide by zero!
Please enter a non-zero second number.
Calculation attempt completed.
Program continues...

🔹 Multiple Exception Handling

Catching different types of exceptions:

public class MultipleExceptions {
    public static void main(String[] args) {
        String[] data = {"10", "20", "abc", "0"};
        int[] numbers = new int[3];
        
        for (int i = 0; i < data.length; i++) {
            try {
                // Convert string to integer
                int value = Integer.parseInt(data[i]);
                
                // Store in array (might cause ArrayIndexOutOfBoundsException)
                numbers[i] = value;
                
                // Perform division (might cause ArithmeticException)
                int result = 100 / value;
                
                System.out.println("Index " + i + ": " + value + ", 100/" + value + " = " + result);
                
            } catch (NumberFormatException e) {
                System.out.println("Index " + i + ": '" + data[i] + "' is not a valid number");
                
            } catch (ArithmeticException e) {
                System.out.println("Index " + i + ": Cannot divide by zero");
                
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("Index " + i + ": Array index out of bounds");
                
            } catch (Exception e) {
                // Catch any other exception
                System.out.println("Index " + i + ": Unexpected error - " + e.getMessage());
            }
        }
        
        System.out.println("Program completed successfully!");
    }
}

Output:

Index 0: 10, 100/10 = 10
Index 1: 20, 100/20 = 5
Index 2: 'abc' is not a valid number
Index 3: Array index out of bounds
Program completed successfully!

🔹 Input Validation Example

Using exceptions for robust user input:

import java.util.Scanner;

public class InputValidation {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int validNumber = 0;
        boolean isValid = false;
        
        System.out.println("=== Number Input Validator ===");
        
        while (!isValid) {
            System.out.print("Enter a positive integer: ");
            
            try {
                String input = scanner.nextLine();
                
                // Try to parse the input
                validNumber = Integer.parseInt(input);
                
                // Check if it's positive
                if (validNumber <= 0) {
                    System.out.println("Please enter a positive number (greater than 0)");
                    continue;
                }
                
                isValid = true;
                System.out.println("Great! You entered: " + validNumber);
                
            } catch (NumberFormatException e) {
                System.out.println("That's not a valid integer. Please try again.");
            }
        }
        
        // Use the valid number
        System.out.println("Square of " + validNumber + " is: " + (validNumber * validNumber));
        
        scanner.close();
    }
}

Sample Output:

=== Number Input Validator ===
Enter a positive integer: abc
That's not a valid integer. Please try again.
Enter a positive integer: -5
Please enter a positive number (greater than 0)
Enter a positive integer: 7
Great! You entered: 7
Square of 7 is: 49

🔹 Throwing Custom Exceptions

Creating and throwing your own exceptions:

public class CustomExceptionExample {
    
    // Method that throws a custom exception
    public static void checkAge(int age) throws IllegalArgumentException {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative: " + age);
        }
        if (age > 150) {
            throw new IllegalArgumentException("Age seems unrealistic: " + age);
        }
        System.out.println("Valid age: " + age);
    }
    
    public static void main(String[] args) {
        int[] testAges = {25, -5, 200, 30};
        
        for (int age : testAges) {
            try {
                System.out.print("Testing age " + age + ": ");
                checkAge(age);
                
            } catch (IllegalArgumentException e) {
                System.out.println("Error - " + e.getMessage());
            }
        }
        
        // Example with array bounds checking
        int[] numbers = {10, 20, 30};
        
        try {
            int index = 5;
            if (index >= numbers.length) {
                throw new IndexOutOfBoundsException("Index " + index + " is out of bounds for array of length " + numbers.length);
            }
            System.out.println("Value at index " + index + ": " + numbers[index]);
            
        } catch (IndexOutOfBoundsException e) {
            System.out.println("Array access error: " + e.getMessage());
        }
    }
}

Output:

Testing age 25: Valid age: 25
Testing age -5: Error - Age cannot be negative: -5
Testing age 200: Error - Age seems unrealistic: 200
Testing age 30: Valid age: 30
Array access error: Index 5 is out of bounds for array of length 3

🔹 Exception Handling Best Practices

Do's:

  • Be specific: Catch specific exceptions rather than generic Exception
  • Use finally: For cleanup code that must run
  • Log errors: Print meaningful error messages
  • Validate input: Check data before processing
  • Handle gracefully: Don't let exceptions crash your program

Don'ts:

  • Don't ignore exceptions: Always handle or log them
  • Don't catch everything: Only catch exceptions you can handle
  • Don't use exceptions for control flow: Use if-else instead
  • Don't throw generic exceptions: Be specific about what went wrong

🧠 Test Your Knowledge

Which block always executes regardless of whether an exception occurs?