Table of contents
1.
Introduction
2.
Hierarchy of Exceptions in Java
3.
Types of Exceptions in Java
3.1.
1. Built-in Exceptions
3.2.
2. User-defined Exceptions
4.
Java Exception Keywords
5.
Mechanism of Exception Handling: Role of JVM
6.
Difference Between Exception and Errors
7.
Difference Between Checked and Unchecked Exceptions
8.
Frequently Asked Questions
8.1.
What is the exception order in Java? 
8.2.
Why do we need Java Exception Handling? 
8.3.
What is the parent class of the exception class?
8.4.
What are the two main subclasses of Throwable?
8.5.
What is the difference between Exception and Throwable?
9.
Conclusion
Last Updated: Feb 4, 2025
Medium

Exception Hierarchy in Java

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Understanding the Exception Hierarchy in Java is essential for handling errors effectively and writing robust applications. Java provides a structured exception-handling mechanism with a well-defined hierarchy, categorizing exceptions into checked and unchecked types. This blog explores the exception hierarchy, its key components, and best practices for managing exceptions efficiently.

Exception Hierarchy in Java

This article is part of a four-blog series on Java exceptions and exception handling. The introduction, hierarchy, built-in, user-defined exceptions and the fundamental differences between exceptions and errors are covered in this part.

Hierarchy of Exceptions in Java

Java is an object-oriented language, and it has a plethora of built-in classes and packages. The lang package of Java provides classes that are fundamental to the design of the Java language. For example, the Object class is part of this package, which is the default parent class of all Java classes. 

The root class of the Java exception is Throwable, which is a subclass of the Object class. Exception and Error both the classes are derived from the Throwable class.

Refer to the diagram given below to understand the hierarchy of exceptions in Java along with their category of checked and unchecked exceptions:

Types of Exceptions in Java

The above diagram shows the two types of exceptions, checked and unchecked, based on the time of occurrence, i.e. compile-time or run-time. Despite the fact that Java has a rich library of predefined or built-in exceptions, it allows programmers to create their own exceptions. 

There are two types of exceptions in Java

  1. Built-in Exception
  2. User Defined Exception


1. Built-in Exceptions

Exceptions that are available in Java libraries are known as built-in exceptions.

Most of these exceptions are subclasses of RuntimeExceptions defined in the java.lang package. Since this package is imported to all the Java programs implicitly, most exceptions derived from RuntimeException are automatically available.

These exceptions are appropriate for explaining particular error situations. Below are some of the notable Java built-in exceptions.
 

1.) ArithmeticException: This exception occurs when a program encounters an error in arithmetic operations such as divide by zero. 

import java.io.*;

public class TestClass {
public static void main(String args[])
    {
            int num1 = 100, num2 = 0;
            int result = num1 / num2; // divide by zero
            System.out.println("Result = " + result);
    }
}

 

Output:

Exception in thread "main" java.lang.ArithmeticException: / by zero
at TestClass.main(Test.java:8)

 

2.) ArrayIndexOutOfBoundsException: This exception is thrown when an array is accessed using an illegal index. The index used is either more than the size of the array or is a negative index. Java doesn’t support negative indexing.

import java.io.*;

public class TestClass {
public static void main(String args[])
    {
        int a[] = new int[6];
        System.out.println(a[6]);
         //indexing starts with zero
        // accessing 7th element in an array of size 6
    }
}

 

Output:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 6 
at TestClass.main(Test.java:6)

 

3.) ClassNotFoundException: This exception is thrown when the JVM tries to load a class, which is not present in the classpath. 

// When we try to run a database connectivity program without adding // jar files to the classpath, a class not found exception arises.

public class Test{
    public static void main(String[] args)
    {
        Class.forName("oracle.jdbc.driver.OracleDriver");
       
    }
}

 

Output:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:     Unhandled exception type ClassNotFoundException
at Test.main(TestClass.java:5)

 

4.) FileNotFoundException: This exception is thrown when the program tries to access a file that does not exist or does not open. This error occurs mainly in file handling programs.

import java.io.*;
public class TestClass {
  
public static void main(String args[])
    {
        // Following file does not exist in the location mentioned
            File file = new File("E:// file.txt");
  
            FileReader fr = new FileReader(file);
        
    }
}

 

Output:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: Unhandled exception type FileNotFoundException
at TestClass.main(TestClass.java:9)

 

5. IOException: This exception is thrown when the input-output operation in a program fails or is interrupted during the program’s execution.

import java.io.*;

public class TestClass 
{
public static void main(String args[])
    {
        FileInputStream f = null;
        f = new FileInputStream("CodingNinjas.txt");
        int i;
        while ((i = f.read()) != -1) {
            System.out.print((char)i);
        }
        f.close();
    }
}

 

Output:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: Unhandled exception type IOException
at TestClass.main(TestClass.java:6)

 

6.) InterruptedException: This exception occurs whenever a thread is processing, sleeping or waiting in a multithreading program and it is interrupted.

import java.io.*;

public class TestClass {
public static void main(String args[])
    {
        Thread t = new Thread();
        t.sleep(10000);
    }
}

 

Output:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: Unhandled exception type InterruptedException
at TestClass.main(TestClass.java:6)

 

7.) NullPointerException: This exception is raised when a null object is referred to in a program. NullPointerException is the most important and common exception in Java.

import java.io.*;

public class TestClass {
public static void main(String args[])
    {
        String a = null; // null value
            System.out.println(a.charAt(0));   
    }
}

 

Output:

Exception in thread "main" java.lang.NullPointerException
at TestClass.main(TestClass.java:6)

 

8.) NumberFormatException: This exception is thrown when a method could not convert a string into a numeric format.

import java.io.*;

public class TestClass {
public static void main(String args[])
    {
        String a = null; // null value
            System.out.println(a.charAt(0));   
    }
}

 

Output:

Exception in thread "main" java.lang.NumberFormatException: For input string: "CodingNinjas" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

 

9.) StringIndexOutOfBoundsException: This exception is thrown by the string class, and it indicates that the index is beyond the size of the string object or is negative.

import java.io.*;

public class TestClass {
public static void main(String args[])
    {
     
            String a = "Coding Ninjas"; // length is 13
            char c = a.charAt(14); // accessing 14th element
            System.out.println(c);
        
    }
}

 

Output:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 14

 

10.) EOFException: This exception is a part of the java.io package and is thrown when the end of the file is reached.

import java.io.*;
import java.util.Scanner;

public class TestClass {
   public static void main(String[] args) throws Exception {
      //Reading from the file using readChar() method
      DataInputStream dis = new DataInputStream(new FileInputStream("D:\\data.txt"));
      while(true) 
      {
         char ch;
            ch = dis.readChar();
            System.out.print(ch);
         
      }
}
}

 

Output:

Exception in thread "main" java.io.EOFException  at java.base/java.io.DataInputStream.readChar(DataInputStream.java:370)
at TestClass.main(TestClass.java:10)

 

11.) IllegalArgumentException: This exception is thrown when invalid arguments are passed to any method in the program. 

//Every thread has a priority, which is a number between 1 and 10
import java.io.*;
public class TestClass {
public static void main(String[] args)
    {
        Thread t = new Thread();
        Thread t1 = new Thread();
        t.setPriority(7); // Correct
        t1.setPriority(17); // Exception
    }
}

 

Output:

Exception in thread "main" java.lang.IllegalArgumentException
at java.base/java.lang.Thread.setPriority(Thread.java:1141)
at TestClass.main(TestClass.java:8)

Other Important Built-in Exceptions in Java

  1. NoSuchFieldException: If a class in a program does not contain a specified field or variable, it throws this exception.
  2. NoSuchMethodException: This exception is raised when the method being accessed is not found.
  3. InputMismatchException: This exception is thrown when the input read does not match a pattern specified. For example, if the program expects an integer and reads a float value
  4. NoSuchElementException: This exception is thrown when the next element accessed in a program does not exist.
  5. ConcurrentModificationException: This exception is usually thrown by Collection classes. This exception is thrown when the objects try to modify a resource concurrently in a program.

2. User-defined Exceptions

So far, we've covered exceptions that the Java language has to offer as built-in/pre-defined java exceptions. In addition to these, we can also create our exceptions as per the requirement. Such exceptions are called custom exceptions or user-defined exceptions.

For Example, If a user wants to make a program accepting candidates with age 18 or more. A custom exception for this problem can be created in the following manner.

Step:1 Create a custom class:

A custom class is created defining the functionality needed to offer.

Step:2 Choose a Superclass for the custom class:

The custom class we have created needs to extend any exception subclass from the hierarchy. However, choosing a random class can be ineffective. Because either they are too specialised or irrelevant to our custom class. So, the best practice is to extend the Exception class itself.

class CustomException extends Exception{  
 CustomException(String s){  
  super(s);  
 }  
} 

 

Step:3 Use custom class in the program 

The program is throwing the custom exception while validating age in the if clause.

class TestCustomException
{  
  static void validate(int age)throws CustomException
  {  
     if(age<18)throw new CustomException("Invalid Age");  
     else  
      System.out.println("Successful!!");  
   }  
     
   public static void main(String args[])
   {  
      try {  
      validate(13);  
      } catch(Exception ex)
      {
       System.out.println("Exception occured: "+ex);
      } 
  }  
}  

Output:

Invalid Age

 

Note: It's fine if you're a beginner and have no idea what these terms mean or how they have been used in the code above. This series is designed to assist you in understanding this topic at all levels. All these terms are thoroughly explained in the topics listed in the introductory part. So don't be discouraged and keep learning.

The significant factor behind the magic of exceptions in Java is JVM. JVM  is short for Java Virtual Machine, which is an abstract machine. It is a specification that provides a runtime environment for executing Java bytecode.

Let's take a closer look at JVM's role in the mechanism of exception.

Java Exception Keywords

Certainly! Here's a table explaining the keywords related to exceptions in Java:

KeywordDescription
tryEncloses a block of code in which exceptions may occur. Use along with catch or finally blocks.
catchFollows a try block and is used to handle specific exceptions that may be thrown within the try block.
finallyOptional block that follows a try block (and optionally a catch block) and is used to execute cleanup code, regardless of whether an exception is thrown or not.
throwUsed to explicitly throw an exception.
throwsUsed in method declarations to indicate that the method may throw one or more exceptions. The caller of the method must handle or propagate these exceptions.
try-with-resourcesIntroduced in Java 7, it automatically closes resources (like streams) declared in its initialization block, ensuring proper cleanup.
throwableSuperclass of all exceptions and errors in Java.
exceptionSuperclass of all checked exceptions.
runtimeexceptionSuperclass of all unchecked exceptions.
errorSuperclass of all errors that typically represent problems that are outside the control of the application.

Mechanism of Exception Handling: Role of JVM

If an exception occurs inside a method, the method creates an Exception Object and sends it off to the run-time system or JVM. Exception Object contains the name, description and current state of the program where the exception has been raised. 

The process of creating an exception object and handing it to JVM is known as throwing an exception

A list of methods could be called to go to the method where the exception occurred. This list of the methods is called Call Stack

Fig: The Call Stack
The step by step procedure of exception handling by JVM  is given below:

  1. The JVM looks through the call stack for an exception handler that can handle the exception. 
  2. The JVM begins its search at the method where the exception occurred and works backwards across the call stack, calling methods in the same order they were called.

Fig: Searching the call stack for the exceptional handler

a.) If a suitable handler is found, the JVM forwards the thrown exception to it. The type of the exception object thrown must match the type of the exception object the handler can handle.

b.) If the JVM explores all of the methods on the call stack and cannot find an appropriate handler, the Exception object is sent to the default exception handler, which is part of the run-time system. This handler prints the exception information and aborts the program.

Difference Between Exception and Errors

Considering the hierarchy of Exceptions in Java as explained above, it can be concluded that both Error and Exception are subclasses of the Throwable parent class. 

The table below shows some of the key differences between exception and error

ParameterExceptionError
DefinitionAn issue that can be handled in the program using try-catch blocks.A serious problem that occurs beyond the control of the program.
PackageBelongs to java.lang.Exception.Belongs to java.lang.Error.
RecoverabilityCan be recovered using exception handling mechanisms.Generally not recoverable, as they indicate serious failures.
ExamplesIOException, SQLException, NullPointerException, ArithmeticException.OutOfMemoryError, StackOverflowError, VirtualMachineError.
CauseUsually caused by logic or programming errors.Occurs due to system-level issues, hardware failures, or resource exhaustion.
Handling MechanismCan be handled using try-catch or throws.Typically not handled, as recovery is impractical.

Difference Between Checked and Unchecked Exceptions

Here's a table that explains the differences between checked and unchecked exceptions in Java:

FeatureChecked ExceptionsUnchecked Exceptions
DefinitionExceptions that are checked at compile-timeExceptions that are checked at runtime
Class HierarchySubclasses of java.lang.Exception (excluding RuntimeException)Subclasses of java.lang.RuntimeException
Handling RequirementMust be either caught or declared to be thrownNot required to be caught or declared
ExamplesIOException, SQLException, FileNotFoundExceptionNullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException
PurposeRepresent conditions that a reasonable application might want to catchRepresent programming errors, such as logic errors or improper use of an API
Error TypeOften result of external factors, outside the control of the programOften result of bugs, such as logic errors
Compiler EnforcementCompiler checks for handling checked exceptionsNo compiler checks for handling unchecked exceptions
Best PracticesShould be handled with care to ensure proper program executionShould be minimized by writing robust code
DocumentationTypically documented with the method signature using throws clauseNot typically documented, but can be described in method comments
RecoveryCan often recover from the exception if handled properlyOften difficult to recover from unchecked exceptions, may need debugging

Frequently Asked Questions

What is the exception order in Java? 

In Java, exceptions follow a hierarchy: Throwable is the superclass, followed by Exception, then RuntimeException, and specific exceptions like IOException, NullPointerException, etc.

Why do we need Java Exception Handling? 

In Java, exception handling is required to prevent the program from terminating unexpectedly.

What is the parent class of the exception class?

The Throwable class is the parent class of all exceptions in Java. It provides methods like getMessage(), printStackTrace(), and getCause(), which help in debugging and handling errors effectively. Both Exception and Error inherit from Throwable.

What are the two main subclasses of Throwable?

The two main subclasses of Throwable are Exception and Error. Exception represents recoverable issues, like IOException or NullPointerException, while Error indicates serious system failures, such as OutOfMemoryError or StackOverflowError, which are typically unrecoverable.

What is the difference between Exception and Throwable?

Throwable is the top-level class for all exceptions and errors in Java. Exception is a subclass of Throwable that represents application-level issues that can be handled using try-catch, whereas Error (another subclass) indicates serious problems beyond program control.

Conclusion

Understanding the Exception Hierarchy in Java is crucial for writing robust and error-free applications. By distinguishing between checked and unchecked exceptions, as well as errors, developers can implement efficient exception-handling mechanisms. Proper handling of exceptions ensures better code maintainability, stability, and improved user experience.

Live masterclass