Java Errors & Exception Handling Tutorial

In this Java tutorial we learn about the different errors our application can generate, known as exceptions.

We learn about compile-time and runtime exceptions, and out-of-our-control type errors and how to handle them with the try..catch..finally statements.

We also discuss how to customize errors with the throw keyword and some common exception types.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What are exceptions

Exceptions (exceptional events) occur when the normal flow of a program is disrupted and the application terminates in an abnormal way.

Exceptions can occur for different reasons. Some are caused by users, others are caused by programmers, some may even be caused by external resources that fail in some way.

Based on the reasons above, we have three exception categories.

1. Checked exceptions, otherwise known as compile-time exceptions.

These exceptions occur when the program actively checks for exceptions at compilation time.

2. Unchecked exceptions, otherwise known as runtime exceptions.

These exceptions include bugs in the code, such as logic errors.

3. Errors.

These are technically not exceptions, but rather problems that arise and are beyond the control of both the user and the programmer.

For example, when a network is not available to connect to, or a stack overflow occurs.

What is exception handling

Exception handling is when a programmer actively checks for exceptions with whichever method the language provides.

To do this, Java provides us with the try..catch..finally construct and throw keyword.

How to handle an exception with try..catch in Java

The try and catch blocks will first try to execute a section of code with the try statement. If the code fails, the exception will be caught by the catch statement, and we can handle them in its code block.

Syntax:
try {

    // section of code to
    // try and execute

} catch(type_of_exception temp_exception_variable) {

    // access the exceptions
    // and handle them here
}

The type_of_exception is specific to what we want to check for and is used in to throw an exception.

We learn more about throwing exceptions further along in this lesson.

First, let’s raise a common error as an example.

Example:
public class Program {
    public static void main(String[] args) {

        // array with 4 elements
        String[] employee = { "John", "Jane", "Jack", "Jill" };

        // try to access the 5th element
        // which doesn't exist
        System.out.println( employee[4] );
    }
}

In the example above, we have an array with 4 elements. We then try to access the 5th element, which doesn’t exist, causing an ‘Array out of bounds’ error.

Output:
 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 4

We can use the try..catch statements to catch this error and write code to handle it when it occurs.

Example:
public class Program {
    public static void main(String[] args) {

        // array with 4 elements
        String[] employee = { "John", "Jane", "Jack", "Jill" };

        try {

            // try to execute code that
            // may cause an error
            System.out.println( employee[4] );

        } catch (Exception e) {

            // if the error occurs
            // execute this code
            System.out.println("Can't access an element that doesn't exist, doofus!");
        }
    }
}

In the example above, we try to access the 5th element in the array in the try block. It still doesn’t exist and will raise an error, except this time the error isn’t handled by the compiler, but by the code we wrote in the catch statement.

The finally statement in Java

The finally statement will execute its code after the try..catch, regardless if an error was caught or not.

Syntax:
try {

    // section of code to
    // try and execute

} catch(type_of_exception temp_exception_variable) {

    // access the exceptions
    // and handle them here

} finally {

    // always execute this code after
    // the try..catch has finished
}
Example:
public class Program {
    public static void main(String[] args) {

        // array with 4 elements
        String[] employee = { "John", "Jane", "Jack", "Jill" };

        try {

            // try to execute code that
            // may cause an error
            System.out.println( employee[3] );

        } catch (Exception e) {

            // if the error occurs
            // execute this code
            System.out.println("Can't access an element that doesn't exist, doofus!");

        } finally {

            System.out.println("The try..catch has finished its execution");
        }
    }
}

This time the code doesn’t produce an error, but the finally statement still prints its message to the console.

How to throw a custom exception in Java

The throw statement allows us to create a custom error and is typically used together with an exception type.

First, we specify the throw keyword, followed by new and the exception_type. We pass the custom error message as an argument to the exception type.

Syntax:
 throw new exception_type("custom error message");

Please see the list below for common exception types in Java.

Example:
public class Program {
    public static void main(String[] args) {

        canVote(17);
    }

    public static void canVote(int age) {

        if (age < 18) {
            // throw a custom error message
            throw new ArithmeticException("Sorry, you're not old enough to vote yet");

        } else {

            System.out.println("Hooray, you can vote");
        }
    }
}

In the example above, we throw a new arithmetic exception error when the person’s age is below 18.

Because we call the method with an age of 17, it will throw an exception with our custom message.

Output:
Exception in thread "main" java.lang.ArithmeticException: Sorry, you're not old enough to vote yet
    at Program.canVote(Program.java:11)
    at Program.main(Program.java:4)

Following is a list of common exception types in Java

TypeDescription
ArithmeticExceptionUsed when an arithmetic operation fails
ArrayIndexOutOfBoundsExceptionUsed when an array is accessed with a non-existing index
ClassNotFoundExceptionUsed when the definition for a class cannot be found
FileNotFoundExceptionUsed when a file cannot be found or opened
IOExceptionUsed when an input-ouput operation fails
InterruptedExceptionUsed when a thread is interrupted while waiting, sleeping, or processing
NoSuchFieldExceptionUsed when a class does not contain the specified property
NoSuchMethodExceptionUsed when a class does not contain the specified method
NullPointerExceptionUsed when trying to refer to a member of a null object, an object that doesn't exist
RuntimeExceptionThis represents any exception that occurs during runtime

Summary: Points to remember

  • Exceptions are events that occur when the flow of the application is disrupted.
  • There are 3 exception categories.
    • Checked exceptions are programmer checked exceptions at compile time with the try..catch..finally construct.
    • Unchecked exceptions are bugs in our code that occur at runtime.
    • Errors are beyond the constrol of a user or programmer, such as a network being down.
  • The ‘try’ block is used to try and execute code that might cause an exception.
  • The ‘catch’ block will catch an exception, if one occurs in the try block, and handle it.
  • The ‘finally’ block will always execute after the try and finally blocks, regardless of the outcome.
  • The ‘throw’ statement allows us to customize the error message of an error.