Exception handling in Java

Exceptions in programming are events that occur during the execution of a program and disrupt the normal flow of its instructions. They are typically used to signal error conditions or other unusual circumstances that the program may encounter, such as trying to divide by zero, attempting to access an out-of-bounds index in an array, or failing to open a file.

Types of Exceptions

  1. Runtime Exceptions: These exceptions occur during the execution of the program and are often due to programming errors, such as logic mistakes or incorrect use of APIs. Examples include:

    • NullPointerException: When an application attempts to use null in a case where an object is required.
    • ArrayIndexOutOfBoundsException: When an attempt is made to access an array element with an invalid index.
    • ArithmeticException: When an exceptional arithmetic condition has occurred, like division by zero.
  2. Checked Exceptions: These exceptions are checked at compile time, and the programmer is required to handle them explicitly. Examples include:

    • IOException: When an input-output operation fails or is interrupted.
    • SQLException: When there is a database access error or other errors related to database operations.
  3. Errors: These are serious problems that a reasonable application should not try to catch. They are generally outside the control of the program and indicate problems like system errors. Examples include:

    • OutOfMemoryError: When the Java Virtual Machine (JVM) cannot allocate an object because it is out of memory.
    • StackOverflowError: When the stack depth limit is exceeded, usually due to deep or infinite recursion.

Exception Handling Mechanism

Most programming languages provide constructs to handle exceptions, ensuring that programs can handle errors gracefully and continue running or terminate cleanly.

In Java

Java uses a combination of try, catch, finally, throw, and throws for exception handling.

  1. try: Encapsulates code that might throw an exception.
  2. catch: Catches and handles the exception.
  3. finally: Contains code that will always execute, regardless of whether an exception was thrown or not.
  4. throw: Used to explicitly throw an exception.
  5. throws: Used in a method signature to declare that the method might throw one or more exceptions.

Example 1:

public class ExceptionExample {
    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[3]); 

// This will throw an ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index is out of bounds!");
        } finally {
            System.out.println("This will always execute.");
        }
    }
}

Example 2:

public class DivisionExample {
    public static void main(String[] args) {
        int numerator = 10;
        int[] denominators = {2, 0, 5};

        for (int denominator : denominators) {
            try {
                int result = divide(numerator, denominator);
                System.out.println("Result: " + result);
            } catch (ArithmeticException e) {
                System.out.println("Cannot divide by zero!");
            } finally {
                System.out.println("Division attempt completed.");
            }
        }
    }

    public static int divide(int num, int denom) {
        return num / denom;
    }
}


Custom Exceptions
Custom exceptions in Java allow you to create your own exceptions tailored to the specific needs of your application. These custom exceptions can be either checked or unchecked.

Checked exceptions are exceptions that are checked at compile-time. When you create a custom checked exception, you need to handle or declare it explicitly in your code. Custom checked exceptions are typically used for conditions that a reasonable application might want to catch.

Unchecked exceptions are exceptions that are not checked at compile-time. They are typically used to indicate programming errors, such as logic errors or improper use of an API. 

Throwing custom exceptions in Java involves defining a new exception class that extends either Exception (for checked exceptions) or RuntimeException (for unchecked exceptions). Once the custom exception class is defined, you can throw instances of it in your code.

Steps to Create and Throw Custom Exceptions
  1. Define the Custom Exception Class: Create a class that extends Exception or RuntimeException.
  2. Throw the Custom Exception: Use the throw keyword to throw an instance of your custom exception.
  3. Handle the Custom Exception: Use try-catch blocks to handle the custom exception where necessary.
Example: Custom Checked Exception

First, let's define a custom checked exception by extending Exception.

class CustomCheckedException extends Exception {
    public CustomCheckedException(String message) {
        super(message);
    }
}
public class Main {
    public static void main(String[] args) {
        try {
            validateAge(15);
        } catch (CustomCheckedException e) {
            System.out.println("Caught custom exception: " + e.getMessage());
        }
    }

    public static void validateAge(int age) throws CustomCheckedException {
        if (age < 18) {
            throw new CustomCheckedException("Age must be 18 or older.");
        }
        System.out.println("Age is valid.");
    }
}

Example: Custom Unchecked Exception

Now, let's define a custom unchecked exception by extending RuntimeException.

class CustomUncheckedException extends RuntimeException {

    public CustomUncheckedException(String message) {
        super(message);
    }
}
public class Main {
    public static void main(String[] args) {
        try {
            checkNumber(-1);
        } catch (CustomUncheckedException e) {
            System.out.println("Caught custom exception: " + e.getMessage());
        }
    }

    public static void checkNumber(int number) {
        if (number < 0) {
            throw new CustomUncheckedException("Number must be non-negative.");
        }
        System.out.println("Number is valid.");
    }
}

Key Points
  • Extending Exception: Use this for checked exceptions. These need to be declared in the method signature using the throws keyword.
  • Extending RuntimeException: Use this for unchecked exceptions. These do not need to be declared or caught.
  • Custom Message: Provide a meaningful message to the custom exception's constructor to describe the error.
  • Throwing the Exception: Use the throw keyword to throw an instance of your custom exception.
  • Handling the Exception: Use try-catch blocks to handle the custom exception where necessary.

By creating custom exceptions, you can handle specific error conditions in a more meaningful and controlled manner.

Comments

Popular posts from this blog

KTU OOP LAB JAVA CSL 203 BTech CS S3 - Dr Binu V P

Syllabus and Practice Questions KTU OOPS Lab Java CSL 203

String Problems