Lesson 44 of 50 – Java Exception Handling
88%

Java Exception Handling

Exception handling in Java helps a program deal with unexpected situations during execution without stopping in an uncontrolled way. Java provides keywords such as try, catch, finally, throw, and throws.

1. What Is an Exception?

An exception is an event that interrupts the normal flow of a program. It can occur when an operation cannot be completed, such as dividing an integer by zero or accessing an invalid array index.

class Main {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;

        int result = a / b;

        System.out.println(result);
    }
}

This program throws an ArithmeticException because an integer cannot be divided by zero. The final print statement is not executed.

Exception handling allows you to detect and respond to many runtime problems.
2. Types of Exceptions and Errors
Category Description Example
Checked exception Must be caught or declared in applicable code. IOException
Unchecked exception A RuntimeException or its subclass; generally not required to be caught or declared. NullPointerException
Error A serious problem generally not intended for ordinary application recovery. OutOfMemoryError

Both exceptions and errors are subclasses of Throwable, but they represent different kinds of problems.

3. The try Block

The try block contains code that may throw an exception. A try block must be followed by at least one catch block or a finally block.

class Main {
    public static void main(String[] args) {
        try {
            int result = 10 / 2;
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero");
        }
    }
}
Output:
5

Since the division succeeds, the catch block does not execute.

4. The catch Block

A catch block handles an exception of a matching type thrown from the associated try block.

class Main {
    public static void main(String[] args) {
        try {
            int a = 10;
            int b = 0;

            System.out.println(a / b);
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero");
        }

        System.out.println("Program continues");
    }
}
Output:
Cannot divide by zero
Program continues

The matching catch block handles the exception, allowing execution to continue after the try-catch statement.

5. Multiple catch Blocks

Multiple catch blocks can handle different exception types. Only the first matching catch block executes for a particular thrown exception.

class Main {
    public static void main(String[] args) {
        try {
            int[] numbers = {10, 20, 30};

            System.out.println(numbers[5]);
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic problem");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Invalid array index");
        } catch (Exception e) {
            System.out.println("Some other exception occurred");
        }
    }
}
Output:
Invalid array index

Put more specific exception types before broader types such as Exception.

6. The finally Block

The finally block is generally used for cleanup code. It normally executes whether the try block completes successfully or an exception is handled.

class Main {
    public static void main(String[] args) {
        try {
            int result = 10 / 2;
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic error");
        } finally {
            System.out.println("Finally block executed");
        }
    }
}
Output:
5
Finally block executed

A finally block is not an absolute guarantee under every circumstance, such as abrupt JVM termination.

7. The throw Keyword

The throw keyword explicitly throws a particular exception object.

class Main {
    public static void main(String[] args) {
        int age = 15;

        try {
            if (age < 18) {
                throw new IllegalArgumentException(
                    "Age must be at least 18"
                );
            }

            System.out.println("Eligible");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }
}
Output:
Age must be at least 18

Here, the program creates and throws an IllegalArgumentException when the age is below 18.

8. The throws Keyword

The throws keyword declares exceptions that a method may pass to its caller. It is commonly used with checked exceptions.

import java.io.IOException;

class Main {
    static void checkFile() throws IOException {
        throw new IOException("File could not be read");
    }

    public static void main(String[] args) {
        try {
            checkFile();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}
Output:
File could not be read

The method declares IOException with throws, and the caller handles it with a try-catch block.

9. Checked and Unchecked Exceptions
Checked Exception Example
import java.io.FileReader;
import java.io.IOException;

class Main {
    public static void main(String[] args) {
        try {
            FileReader reader =
                new FileReader("data.txt");

            reader.close();

            System.out.println("File closed");
        } catch (IOException e) {
            System.out.println("File operation failed");
        }
    }
}

FileReader can throw IOException, which must be caught or declared. The file must exist and be accessible for the operation to succeed.

Unchecked Exception Example
class Main {
    public static void main(String[] args) {
        try {
            String name = null;
            System.out.println(name.length());
        } catch (NullPointerException e) {
            System.out.println("Name cannot be null");
        }
    }
}
Output:
Name cannot be null
10. Custom Exceptions

You can create your own exception class by extending Exception for a checked exception or RuntimeException for an unchecked exception.

class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

class Main {
    static void checkAge(int age)
            throws InvalidAgeException {

        if (age < 18) {
            throw new InvalidAgeException(
                "Age must be 18 or above"
            );
        }

        System.out.println("Age accepted");
    }

    public static void main(String[] args) {
        try {
            checkAge(16);
        } catch (InvalidAgeException e) {
            System.out.println(e.getMessage());
        }
    }
}
Output:
Age must be 18 or above

Since InvalidAgeException extends Exception, it is a checked exception.

11. Exception Class Hierarchy
Object
  └── Throwable
      ├── Error
      └── Exception
          ├── IOException
          └── RuntimeException
              ├── ArithmeticException
              ├── NullPointerException
              └── IndexOutOfBoundsException

Java's exception hierarchy starts with Throwable. Exception represents conditions applications may handle, while Error represents serious problems that applications generally should not try to recover from.

RuntimeException and its subclasses are unchecked. Other exception subclasses are generally checked unless they belong to a different unchecked category.
12. Best Practices for Exception Handling
  • Catch specific exceptions when possible.
  • Do not silently ignore exceptions.
  • Use meaningful error messages.
  • Use finally or try-with-resources for cleanup when appropriate.
  • Do not use exceptions as a replacement for ordinary program logic.
  • Do not catch Error for routine application recovery.
Try-with-resources Example
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class Main {
    public static void main(String[] args) {
        try (BufferedReader reader =
                 new BufferedReader(
                     new FileReader("data.txt"))) {

            System.out.println(reader.readLine());

        } catch (IOException e) {
            System.out.println("Could not read the file");
        }
    }
}

Try-with-resources automatically closes resources that implement AutoCloseable when the try statement finishes.

13. Practice Assignments
  1. Write a program that handles division by zero using try and catch.
  2. Create an integer array and handle an invalid index using ArrayIndexOutOfBoundsException.
  3. Write a program demonstrating multiple catch blocks.
  4. Demonstrate the finally block.
  5. Use throw to reject an invalid age.
  6. Create a method that declares IOException using throws.
  7. Create a custom InvalidAgeException class.
  8. Read a file using try-with-resources and handle IOException.
Practice Tip: Test each program with both valid and invalid inputs to understand how exceptions change the program's execution flow.

🧠 Quick Quiz

1. Which keyword is used to handle an exception?




2. Which keyword declares exceptions a method may pass to its caller?




3. Which block is commonly used for cleanup code?