Exception Handling in Java

Exception Handling in Java is one of the effective means to handle runtime errors so that the regular flow of the application can be preserved. Java Exception Handling is a mechanism to handle runtime errors such as ClassNotFoundException, IOException, SQLException, RemoteException, etc.

What are Java Exceptions?
In Java, Exception is an unwanted or unexpected event, which occurs during the execution of a program, i.e. at run time, that disrupts the normal flow of the program’s instructions. Exceptions can be caught and handled by the program. When an exception occurs within a method, it creates an object. This object is called the exception object. It contains information about the exception, such as the name and description of the exception and the state of the program when the exception occurred.

Major reasons why an exception Occurs
  • Invalid user input
  • Device failure
  • Loss of network connection
  • Physical limitations (out-of-disk memory)
  • Code errors
  • Out of bound
  • Null reference
  • Type mismatch
  • Opening an unavailable file
  • Database errors
  • Arithmetic errors
Errors represent irrecoverable conditions such as Java virtual machine (JVM) running out of memory, memory leaks, stack overflow errors, library incompatibility, infinite recursion, etc. Errors are usually beyond the control of the programmer, and we should not try to handle errors.

Difference between Error and Exception

Let us discuss the most important part which is the differences between Error and Exception that is as follows: 
  • Error: An Error indicates a serious problem that a reasonable application should not try to catch.
  • Exception: Exception indicates conditions that a reasonable application might try to catch.
Exception Hierarchy

All exception and error types are subclasses of the class Throwable, which is the base class of the hierarchy. One branch is headed by Exception. This class is used for exceptional conditions that user programs should catch. NullPointerException is an example of such an exception. Another branch, Error is used by the Java run-time system(JVM) to indicate errors having to do with the run-time environment itself(JRE). StackOverflowError is an example of such an error.

Exception Hierarchy in Java

Types of Exceptions

Java defines several types of exceptions that relate to its various class libraries. Java also allows users to define their own exceptions.

Types of Exceptions in Java

Exceptions can be categorized in two ways:

  1. Built-in Exceptions
    • Checked Exception
    • Unchecked Exception 
  2. User-Defined Exceptions

Let us discuss the above-defined listed exception that is as follows:

1. Built-in Exceptions

Built-in exceptions are the exceptions that are available in Java libraries. These exceptions are suitable to explain certain error situations.

  • Checked Exceptions: Checked exceptions are called compile-time exceptions because these exceptions are checked at compile-time by the compiler.
     
  • Unchecked Exceptions: The unchecked exceptions are just opposite to the checked exceptions. The compiler will not check these exceptions at compile time. In simple words, if a program throws an unchecked exception, and even if we didn’t handle or declare it, the program would not give a compilation error.

2. User-Defined Exceptions:

Sometimes, the built-in exceptions in Java are not able to describe a certain situation. In such cases, users can also create exceptions, which are called ‘user-defined Exceptions’. 

The advantages of Exception Handling in Java are as follows:

  1. Provision to Complete Program Execution
  2. Easy Identification of Program Code and Error-Handling Code
  3. Propagation of Errors
  4. Meaningful Error Reporting
  5. Identifying Error Types

Checked Exceptions in Java
These are the exceptions that are checked at compile time. If some code within a method throws a checked exception, then the method must either handle the exception or it must specify the exception using the throws keyword. Checked exceptions can be fully checked or partially checked.
  • Fully Checked Exception: A checked exception where all its child classes are also checked (e.g., IOExceptionInterruptedException).
  • Partially Checked Exception: A checked exception where some of its child classes are unchecked (e.g., Exception).

Checked exceptions represent invalid conditions in areas outside the immediate control of the program (like memory, network, file system, etc.). Any checked exception is a subclass of Exception. Unlike unchecked exceptions, checked exceptions must be either caught by the caller or listed as part of the method signature using the throws keyword.

// Java Program to Illustrate Checked Exceptions
// Where FileNotFoundException occurred

// Importing I/O classes
import java.io.*;

// Main class
class Test {

    // Main driver method
    public static void main(String[] args)
    {

        // Reading file from path in local directory
        FileReader file = new FileReader("C:\\test\\a.txt");

        // Creating object as one of ways of taking input
        BufferedReader fileInput = new BufferedReader(file);

        // Printing first 3 lines of file "C:\test\a.txt"
        for (int counter = 0; counter < 3; counter++)
            System.out.println(fileInput.readLine());

        // Closing file connections
        // using close() method
        fileInput.close();
    }
}
java: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
To fix the above program, we either need to specify a list of exceptions using throws, or we need to use a try-catch block. We have used throws in the below program. Since FileNotFoundException is a subclass of IOException, we can just specify IOException in the throws list and make the above program compiler-error-free.
// Java Program to Illustrate Checked Exceptions
// Where FileNotFoundException does not occur

// Importing I/O classes
import java.io.*;

// Main class
class Test {

    // Main driver method
    public static void main(String[] args)
        throws IOException
    {

        // Creating a file and reading from local repository
        FileReader file = new FileReader("C:\\test\\a.txt");

        // Reading content inside a file
        BufferedReader fileInput = new BufferedReader(file);

        // Printing first 3 lines of file "C:\test\a.txt"
        for (int counter = 0; counter < 3; counter++)
            System.out.println(fileInput.readLine());

        // Closing all file connections
        // using close() method
        // Good practice to avoid any memory leakage
        fileInput.close();
    }
}
Output: First three lines of file "C:\test\a.txt"

Unchecked Exceptions in Java
These are the exceptions that are not checked at compile time. In C++, all exceptions are unchecked, so it is not forced by the compiler’s to either handle or specify the exception. It is up to the programmers to be civilized and specify or catch the exceptions. In Java, exceptions under Error and RuntimeException classes are unchecked exceptions, everything else under throwable is checked. 
// Java Program to Illustrate Un-checked Exceptions

// Main class
class GFG {

    // Main driver method
    public static void main(String args[])
    {
        // Here we are dividing by 0
        // which will not be caught at compile time
        // as there is no mistake but caught at runtime
        // because it is mathematically incorrect
        int x = 0;
        int y = 10;
        int z = y / x;
    }
}
Output : Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Main.main(Main.java:5)
Java Result: 1

Consider the above Java program. It compiles fine, but it throws ArithmeticException when run. The compiler allows it to compile because ArithmeticException is an unchecked exception.
In short unchecked exceptions are runtime exceptions that are not required to be caught or declared in a throws clause. 
These exceptions are usually caused by programming errors, such as attempting to access an index out of bounds in an array or attempting to divide by zero.
Unchecked exceptions include all subclasses of the RuntimeException class, as well as the Error class and its subclasses.

Java Keywords Related to Exception

So, how does Java handle these exceptions? In Java, there are several keywords such as throwsthrowtryfinallycatch to assist you in handling exceptions. Let's discuss them separately below.

throws and throw

In Java, an exception is an object that can be thrown either custom-defined by programmers or thrown by the application. It must be defined and thrown with the help of the throws and throw statements.

throws and throw usually appear in pairs. For example,

static void cacheException() throws Exception {
  throw new Exception();
}

Understanding from the Perspective of Responsibility Division:

  • throw is used within a method body to indicate that an exception is thrown and will be handled by the statements within the method body.
  • throws is used after a method declaration to indicate that the exception is re-thrown and will be handled by the caller of the method.

Understanding from the Perspective of Function Execution:

  • throws mainly declares that this method will throw an exception of this type, making its callers aware that they need to catch this exception.
  • throw is the specific action of throwing an exception outward, so it throws an instance of an exception.

Post a Comment

Previous Post Next Post