Creating Custom Java Exceptions

JavaJavaBeginner
Practice Now

Introduction

In Java, exceptions are thrown to indicate exceptional events that occur during the execution of a program. While Java provides a range of in-built exceptions, sometimes we may need to define our own custom exception for specific situations. There are two types of custom exceptions: checked and unchecked exceptions. Checked exceptions are those that need to be handled during compile time, whereas unchecked exceptions are only detected during runtime. In this lab, we will create both types of custom exceptions and learn how to use them.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("`Java`")) -.-> java/ProgrammingTechniquesGroup(["`Programming Techniques`"]) java(("`Java`")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["`Object-Oriented and Advanced Concepts`"]) java(("`Java`")) -.-> java/BasicSyntaxGroup(["`Basic Syntax`"]) java(("`Java`")) -.-> java/DataStructuresGroup(["`Data Structures`"]) java(("`Java`")) -.-> java/StringManipulationGroup(["`String Manipulation`"]) java(("`Java`")) -.-> java/SystemandDataProcessingGroup(["`System and Data Processing`"]) java/ProgrammingTechniquesGroup -.-> java/scope("`Scope`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("`Classes/Objects`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/class_methods("`Class Methods`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/constructors("`Constructors`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("`Exceptions`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/inheritance("`Inheritance`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/modifiers("`Modifiers`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/oop("`OOP`") java/BasicSyntaxGroup -.-> java/identifier("`Identifier`") java/DataStructuresGroup -.-> java/arrays("`Arrays`") java/BasicSyntaxGroup -.-> java/comments("`Comments`") java/BasicSyntaxGroup -.-> java/data_types("`Data Types`") java/BasicSyntaxGroup -.-> java/for_loop("`For Loop`") java/BasicSyntaxGroup -.-> java/if_else("`If...Else`") java/BasicSyntaxGroup -.-> java/operators("`Operators`") java/BasicSyntaxGroup -.-> java/output("`Output`") java/StringManipulationGroup -.-> java/strings("`Strings`") java/BasicSyntaxGroup -.-> java/variables("`Variables`") java/SystemandDataProcessingGroup -.-> java/system_methods("`System Methods`") subgraph Lab Skills java/scope -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/classes_objects -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/class_methods -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/constructors -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/exceptions -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/inheritance -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/modifiers -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/oop -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/identifier -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/arrays -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/comments -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/data_types -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/for_loop -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/if_else -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/operators -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/output -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/strings -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/variables -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} java/system_methods -.-> lab-117405{{"`Creating Custom Java Exceptions`"}} end

Create a Java Class Named MyArray

First, we will create a Java class named MyArray to implement an array with the get() method, which may throw an exception if the index is invalid.

public class MyArray {
    int[] array;

    public MyArray(int size) {
        array = new int[size];
        for (int i = 0; i < size; i++) {
            array[i] = i * 5;
        }
    }

    // Get method that may throw an exception
    public int get(int index) {
        if (index >= array.length) {
            throw new IndexOutOfBoundsException("Index " + index + " is invalid.");
        } else {
            return array[index];
        }
    }
}

Create a Custom Checked Exception

We can create a custom checked exception by extending the Exception class. In this example, we will create an IndexNotValidException when the index is invalid. This exception will be thrown by the get() method in the MyArray class.

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

We can now update the get() method in the MyArray class to throw this custom exception.

public int get(int index) throws IndexNotValidException {
    if (index >= array.length) {
        throw new IndexNotValidException("Index " + index + " is invalid.");
    } else {
        return array[index];
    }
}

Handle the Custom Checked Exception

To handle the custom checked exception, we need to catch it or declare it using throws keyword when get() method is called in the Demo class.

public class Demo {
    public static void main(String[] args) {
        MyArray arr = new MyArray(5);
        try {
            System.out.println(arr.get(10)); // Throws IndexNotValidException
        } catch (IndexNotValidException e) {
            System.err.println(e.getMessage());
        }
    }
}

Create a Custom Unchecked Exception

We can create a custom unchecked exception by extending the RuntimeException class instead of the Exception class. In the following example, we will create an IndexNotValidRuntimeException when the index is invalid, which will be thrown by the get() method in the MyArray class.

public class IndexNotValidRuntimeException extends RuntimeException {
    public IndexNotValidRuntimeException(String message, Throwable cause) {
        super(message, cause);
    }
}

In addition, we define a throwable exception that defines the underlying exception or the cause of our exception. In our case, the underlying exception is ArrayIndexOutOfBounds. We can update the get() method in the MyArray class to throw the custom unchecked exception.

public int get(int index) {
    if (index >= array.length) {
        Throwable cause = new ArrayIndexOutOfBoundsException();
        throw new IndexNotValidRuntimeException("Index " + index + " is invalid.", cause);
    } else {
        return array[index];
    }
}

Handle the Custom Unchecked Exception

We do not need to catch or declare the custom unchecked exception. In the following example, when the get() method is called with an invalid index in the Demo class, an IndexNotValidRuntimeException will be thrown.

public class Demo {
    public static void main(String[] args) {
        MyArray arr = new MyArray(5);
        System.out.println(arr.get(10)); // Throws IndexNotValidRuntimeException
    }
}

Summary

Custom Java exceptions can help us to handle specific errors or exceptions in our application effectively by creating exceptions that are tailored to our needs. In this lab, we have learned how to create our own custom exceptions to handle errors in our business logic or workflow. We have also discussed how to create both checked and unchecked exceptions, with examples of each.

Other Java Tutorials you may like