Java Exception Handling
Exception handling in Java is a powerful mechanism that handles runtime errors, ensuring the normal flow of the program. This tutorial will cover the basics of exception handling, including types of exceptions, try-catch blocks, finally blocks, and custom exceptions.
Key Concepts
- Exception Hierarchy
- Try-Catch Block
- Finally Block
- Throw and Throws
- Custom Exceptions
1. Exception Hierarchy
In Java, all exceptions are represented by classes that are part of the java.lang package. The root class of the exception hierarchy is Throwable.
- Checked Exceptions: These are checked at compile-time (e.g., IOException,SQLException).
- Unchecked Exceptions: These are checked at runtime (e.g., ArithmeticException,NullPointerException).
- Errors: These are serious problems that a reasonable application should not try to catch (e.g., OutOfMemoryError,StackOverflowError).
2. Try-Catch Block
The try block contains the code that might throw an exception, and the catch block contains the code to handle the exception.
  public class Main {
    public static void main(String[] args) {
        try {
            int divideByZero = 5 / 0;
        } catch (ArithmeticException e) {
            System.out.println("ArithmeticException: Cannot divide by zero.");
        }
    }
}
  
  3. Finally Block
The finally block contains the code that will always be executed, regardless of whether an exception is thrown or not.
  public class Main {
    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("ArrayIndexOutOfBoundsException: Index out of bounds.");
        } finally {
            System.out.println("This will always be executed.");
        }
    }
}
  
  4. Throw and Throws
The throw keyword is used to explicitly throw an exception, while throws is used in method signatures to declare that a method can throw an exception.
  // Using throw
public class Main {
    public static void validateAge(int age) {
        if (age < 18) {
            throw new IllegalArgumentException("Age must be 18 or above.");
        }
    }
    public static void main(String[] args) {
        try {
            validateAge(15);
        } catch (IllegalArgumentException e) {
            System.out.println("Exception: " + e.getMessage());
        }
    }
}
// Using throws
import java.io.IOException;
public class Main {
    public static void readFile() throws IOException {
        throw new IOException("File not found");
    }
    public static void main(String[] args) {
        try {
            readFile();
        } catch (IOException e) {
            System.out.println("IOException: " + e.getMessage());
        }
    }
}
  
  5. Custom Exceptions
You can create your own exceptions by extending the Exception class.
  class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}
public class Main {
    public static void checkNumber(int number) throws CustomException {
        if (number < 0) {
            throw new CustomException("Number cannot be negative.");
        }
    }
    public static void main(String[] args) {
        try {
            checkNumber(-5);
        } catch (CustomException e) {
            System.out.println("CustomException: " + e.getMessage());
        }
    }
}