Types of Exceptions in Java

Java is an object-oriented programming language. It supports a variety of techniques, including exception handling. This Java feature allows developers to control exception-related runtime issues.

In Java, an exception is an event that happens during the execution of a program and prevents the program's instructions from flowing normally. Exceptions are bugs or errors that we don't want and that prevent our application from running normally.

In this article, we are discussing exceptions in Java. You'll also learn about the various types of exceptions that can occur in Java.

We will cover the following:

  1. What is an Exception?
  2. Java Exceptions Hierarchy
  3. What are the Types of Exception?

What is an Exception?

An event that occurs during a program's execution and prevents the program's instructions from flowing normally is called an exception. It is an unwanted or unexpected event that can occur in application code at compile-time or during run-time.

The occurrence of exceptions might be due to a variety of factors. An exception may be made in the following scenarios:

  • Whenever a user gives incorrect information
  • The file you're looking for doesn't exist in the system
  • When the Java Virtual Machine (JVM) becomes memory constrained
  • The network goes down in the middle of a conversation

When a method identifies an error, it generates an object and sends it to the runtime system to be processed. The exception object contains details about the error, such as its nature and the program's current state at the time of occurrence.

The process of producing an exception object and passing it to the runtime system is known as throwing an exception.

When a method throws an exception, the runtime system tries to figure out how to handle the situation. The ordered list of methods that were called to arrive in the method where the error occurred is the set of available "somethings" to handle the exception. The call stack consists of a set of methods.

The runtime system looks up a method in the call stack that has a block of code that can handle the exception. An exception handler is a name given to this section of code.

The search starts with the method where the error occurred and moves backwards across the call stack, calling the methods in the sequence they were called.

The runtime system passes the exception to the handler when an appropriate handler is located. If the type of the exception object thrown matches the type that the handler can handle, the handler is considered appropriate.

Java Exceptions Hierarchy

All exception types are subclasses of Throwable, which is a built-in class. As a result, Throwable is at the very top of the exception hierarchy. Two subclasses just below Throwable divide exceptions into two separate branches.

Image Source

An Exception is in charge of one branch. This is a tried-and-true method for detecting unusual circumstances that user programs should be aware of. This is also the class you'll subclass in order to make your own unique exception kinds.

The other branch is headed by Error, which describes exceptions that your program isn't meant to catch under typical conditions. The Java runtime system uses exceptions of type Error to highlight errors that are related to the runtime environment.

What are the Types of Exception?

In Java, there are primarily two types of exceptions:

  1. Checked Exception
  2. Unchecked Exception

#1 Checked Exception

A checked exception must be handled in Java source code, either by catching it or declaring it as thrown. Checked exceptions are typically generated by errors outside of the code, such as missing resources, networking errors, or threading issues. These might include FileNotFoundException subclasses, UnknownHostException subclasses, and so on.

Programmers should expect checked exceptions, and programs should be able to recover from them. Except for the Error and RuntimeException classes and their subclasses, all Java exceptions are checked exceptions.

import java.io.*;

class FilePrinterExample {

    public static void main(String args[]) {

        FileInputStream inputStream = null;

        inputStream = new FileInputStream("D:/file.txt");
        // file.txt does not exist at the location

        int m;
        while ((m = inputStream.read()) != -1) {
            System.out.print((char) m);
        }

        inputStream.close();
    }
}

Result:

Exception in thread "main"
java.lang.Error: Unresolved compilation problems:
    Unhandled exception type FileNotFoundException
Unhandled exception type IOException
Unhandled exception type IOException

The fact that the program throws exceptions throughout the compilation process is readily visible in the output. There are two approaches to resolving such issues.

throws keyword

With the help of the throws keyword, you can declare an exception.

import java.io.*;

class FilePrinterExample {

    public static void printFile(String args[]) throws IOException {

        FileInputStream inputStream = null;

        inputStream = new FileInputStream("D:/file.txt");
        // file.txt does not exist at the location

        int m;
        while ((m = inputStream.read()) != -1) {
            System.out.print((char) m);
        }

        inputStream.close();
    }
}

The method which is calling printFile method must handle the exceptions.

try-catch block

There is an alternative to the procedure described above for resolving exceptions. Using try-catch blocks, you can keep track of them.

import java.io.*;

class FilePrinterExample {

    public static void printFile(String args[]) {

        FileInputStream inputStream = null;

        try {
        
            inputStream = new FileInputStream("D:/file.txt");
            // file.txt does not exist at the location

        } catch (FileNotFoundException ex) {
            system.out.println("The file does not exist");
            return;
        }

        
        try {

            int i;
            while ((i = inputStream.read()) != -1) {
                System.out.print((char) i);
            }
            
        } catch (IOException ex) {
            system.out.println("I/O error occurred: " + ex);
        } finally {
            inputStream.close();
        }

    }
}

The code will run without a hitch, and the file will appear.

Let's look at some more checked exceptions now. Here are a few examples:

#1 IOException

When an Input/Output operation fails, a method throws an IOException or a direct subclass of it.

Working with the file system or data streams with the java.io package and creating network applications with the java.net package are two common uses of these I/O operations.

import java.io.*;

public class FileReaderSample {

    private static String filepath = "D:\User\guest\Desktop\File2.txt";

    public static void main(String[] args) {

        BufferedReader reader = null;
        String line;

        try {

            reader = new BufferedReader(new FileReader(filepath));
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            System.err.println("IOException found : " + e.getMessage());
        } finally {

            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

An IOException will be thrown by this code.

#2 ClassNotFoundException

When the JVM is unable to locate the needed class, this exception is raised. A command-line error, a classpath issue, or a missing.class file could all be to blame.

To exemplify this type of exception, consider the following code snippet:

public class ClassLoader {

    private static final String CLASS_TO_LOAD = "com.mycompany.perf.Utils";

    public static void main(String[] args) {

        try {

            Class loadedClass = Class.forName(CLASS_TO_LOAD);
            System.out.println("Class " + loadedClass + " found!");

        } catch (ClassNotFoundException ex) {

            System.err.println("Class not found: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

A ClassNotFoundException will be thrown as a result of this code.

#3 InterruptedException

When a Java thread invokes join(), sleep(), or wait(), it enters one of two states: WAITING or TIMED_WAITING.

In addition, a thread can invoke the interrupt() method of another thread to interrupt it.

As a result, if another thread interrupts it while it is in the WAITING or TIMED_WAITING state, the thread throws an InterruptedException.

Consider the following two-thread example:

  1. The main thread initiates and interrupts the child thread
  2. The child thread begins with the sleep() function

In this case, an InterruptedException is thrown:

class ChildThread extends Thread {

    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            LOGGER.error("InterruptedException caught!");
        }
    }

}
public class MainThread {

    public static void main(String[] args)
    
    throws InterruptedException {
        ChildThread childThread = new ChildThread();
        childThread.start();
        childThread.interrupt();
    }
}

#4 SQL Exception

This type of exception arises while using SQL syntax to execute queries on a database.

To exemplify this type of exception, consider the following code snippet:

public void setClientInfo(String name, String value) throws SQLClientInfoException {

    try {
        checkClosed();

        ((java.sql.Connection) this.mc).setClientInfo(name, value);

    } catch (SQLException sqlEx) {

        try {
            checkAndFireConnectionError(sqlEx);

        } catch (SQLException sqlEx2) {
            SQLClientInfoException infoEx = new SQLClientInfoException();
            infoEx.initCause(sqlEx2);
            throw infoEx;
        }
    }
}

A SQLException will be thrown by this code.

#2 Unchecked Exception

The checked and unchecked exceptions are diametrically opposed. These exceptions will not be checked by the compiler at compilation time.

In another way, if a program throws an unchecked exception, the program will not throw a compilation error even if we don't handle or declare it. It usually happens when a user submits incorrect data during a program interaction.

Consider the following code sample to illustrate the concept of an unchecked exception:

import java.util.Scanner;

public class SampleRunTimeError {

    public static void main(String[] args) {

        // Reading user input
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter your age (number): ");

        int age = scanner.nextInt();
        if (age > 18) {
            System.out.println("You can view the page.");
        } else {
            System.out.println("You can't view the page!");
        }
    }
}

Result 1:

Enter your age in Numbers: 21
You can view the page

Result 2:

Enter your age in Numbers: Twelve
Exception in thread“ main” java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at exceptiondemo.sample_runtimedemo.main(SampleRunTimeError.java: 11)

Let's look at some other unchecked exceptions now. Here are a few examples:

#1 NullPointerException

When you try to retrieve an object using a reference variable whose current value is null or empty, you'll get this exception.

To exemplify this type of exception, consider the following code snippet:

class NullPointerSample {

    public static void main(String args[]) {

        try {
            String name = null; 
            System.out.println(name.charAt(0));

        } catch (NullPointerException e) {
            System.out.println("Something went wrong " + e);
        }
    }
}

In the program, a NullPointerException occurs.

#2 ArrayIndexOutOfBoundsException

An array stores its elements in a logical order. As a result, we may use indices to retrieve its elements.

When you try to access an array with an invalid index value, you'll get this error. The value you've provided is either negative or exceeds the array's length.

If a piece of code tries to access an array index that is out of bounds, the method will throw an ArrayIndexOutOfBoundException.

To exemplify this type of exception, consider the following code snippet:

class ArrayIndexSample {

    public static void main(String args[]) {

        try {
            int b[] = new int[6];

            // Trying to access 9th element in an array of size 6
            b[8] = 2; 

        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("The array index is out of bound");
        }
    }
}

The array's index is out of bounds.

#3 IllegalArgumentException

When an improper or erroneous argument is supplied to a method, this type of exception occurs. If a method is defined with non-empty string parameters, for example. You, on the other hand, are providing null input strings.

The IllegalArgumentException is then thrown to inform the user that a null input string cannot be passed to the method.

To exemplify this type of exception, consider the following code snippet:

import java.io.File;

public class URLHelper {

    public static String getFullURL(String domain, String path) throws IllegalArgumentException {

        if (domain == null) {
            throw new IllegalArgumentException("Path is missing!");
        }

        if (path == null) {
            throw new IllegalArgumentException("Path is missing!");
        }

        return domain + File.separator + path;
    }

    public static void main(String[] args) {

        // Valid use case
        system.out.println(URLHelper.getFullURL("www.acme.com", "/users"));

        // Invalid use case
        System.out.println(URLHelper.getFullURL(null, "/users"));
    }
}

An IllegalArgumentException will be thrown by this code.

#4 IllegalStateException

When the state of the environment does not match the operation being performed, this type of exception arises. Consider the following code snippet, which shows how to handle this type of exception:

public void checkPublishedDate() throws IllegalStateException {

    Date publishedAt = getPublishedAt();

    if (publishedAt instanceof Date) {
       System.out.println('Published Date is " + publishedAt);

    } else {
        throw new IllegalStateException("Invalid published date!");
    }
}

IllegalStateException will be thrown by this code.

If a publishing date is already in the system, an IllegalStateException will be thrown, indicating that the book cannot be published again.

#5 NumberFormatException

When you give a string to a method that can't be turned into a number, you'll get this exception.

To exemplify this type of exception, consider the following code snippet:

class SampleNumberFormat {

    public static void main(String args[]) {

        try {

            // "Test" is not a number
            int n = Integer.parseInt("Test");
            System.out.println(n);

        } catch (NumberFormatException e) {
            System.out.println("Number format exception");
        }
    }
}

NumberFormatException will be thrown by this code.

#6 ArithmeticException

When you do an improper arithmetic operation, you get this exception. ArithmeticException is thrown when a program evaluates an arithmetic operation and the result is an exceptional circumstance.

Furthermore, ArithmeticException exclusively affects int and long data types.

For example, if you divide any number by 0, an exception will appear. To exemplify this type of exception, consider the following code snippet:

class SampleArithmetic {

    public static void main(String args[]) {

        try {
            int p = 30;
            int q = 0;

            int r = p / q; // It cannot be divided by zero

            System.out.println("Result = " + r);

        } catch (ArithmeticException e) {
            System.out.println("Number cannot be divided by 0");
        }
    }
}

Summary

We first discussed what exceptions are in this article. An event that occurs during a program's execution and prevents the program's instructions from flowing normally is called an exception.

Checked Exceptions and Unchecked Exceptions were the two categories of the exceptions. Following that, we went over the various types of exceptions that can occur during the compile-time or during run-time.

We hope that this blog has answered all of your doubts and questions about Java exceptions.


Monitor Your Java Applications with Atatus

Atatus keeps track of your Java application to give you a complete picture of your clients' end-user experience. You can determine the source of delayed load times, route changes, and other issues by identifying frontend performance bottlenecks for each page request.

To make bug fixing easier, every Java error is captured with a full stack trace and the specific line of source code marked. To assist you in resolving the Java error, look at the user activities, console logs, and all Java events that occurred at the moment. Error and exception alerts can be sent by email, Slack, PagerDuty, or webhooks.

Try Atatus’s entire features free for 14 days.