Exception handling in Java


JavaViews 2082

Exception handling in Java is one of the most important concepts in Java programming. Whenever we develop software we must ensure that we handle the java exceptions correctly. In this tutorial, we will understand about java exceptions and its types along with important terminologies that we use in exception handling.

What is an exception

In Java, an exception is a condition that stops or terminates the execution process when it encounters an unexpected condition. This interrupts the normal execution flow and throws a system-generated message which the user might not understand. We can handle this situation in java by providing a meaningful message to the user when an exception occurs.

When does an exception occur

Exceptions can occur either due to human error or program error. Below are a few reasons when a java exception occurs:

  • Providing bad user input data
  • Opening a file that does not exist
  • Accessing an array element whose index does not exist
  • Bad network or network connection issues

Advantages of exception handling in Java

  • Does not terminate the execution flow
  • Handles the exception and proceeds with remaining program execution

Let us understand the advantage of exception handling with a simple example. Suppose we have around 100 statements to execute and an exception occurs in the 25th statement that is not handled, then it forces the program to stop the execution, and it will never execute the statements from 26 to 100. In order to overcome this, if we handle the exception that arises in the 25th statement, then instead of terminating the remaining execution, it handles the same and continues the entire program execution until the last 100th statement.

Exception hierarchy in Java

Exception handing in Java

Types of Java exceptions

We can classify java exceptions into two categories:

  • Checked exceptions:
  • Unchecked exceptions:

Checked exceptions

We can also name them as compilation exceptions which means the compiler handles them during the code compilation. In other words, it checks the exception during compilation and warns the developer that there are chances for an exception to occur. In this case, the developer has to handle it in the code. Example: IOException, FileNotFoundException, etc

Example

Below is an example of a checked exception. Suppose we have a class inside which we try to use a FileReader class. We can get file-related exceptions if we do not handle them. Hence the compiler throws a warning to handle the exception if we do not handle it.

import java.io.*;

public class CheckedExceptions {

  public static void main(String[] args) {
    String filename = "D:\\CheckedExceptions.txt";
    File f = new File(filename);
    FileReader fr = new FileReader(f);
  }

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

  at CheckedExceptions.main(CheckedExceptions.java:8)

We can implement checked exception handling in 2 different ways:

Using throws keyword

We can use the throws keyword in the method declaration to handle the exception type. Below is an example to handle FileNotFoundException. But this is not a good approach since we are not providing any user-friendly message and it generates system messages which the user may not understand.

import java.io.*;

public class CheckedExceptions {
  
  public void readFile() throws FileNotFoundException {
    String filename = "D:\\CheckedException.txt";
    File f = new File(filename);
    FileReader fr = new FileReader(f);
  }


  
}

Using try-catch block

We use try-catch keywords as a combination where we write the code that may produce exceptions inside the try block and mention the exception message inside the catch block. This is the best approach since we can clearly mention the exception reason inside the catch block. We will discuss in detail about try-catch block in a separate tutorial.

import java.io.*;

public class CheckedExceptions {
  
  public void readFile() {
    String filename = "D:\\CheckedException.txt";
    File f = new File(filename);
    try {
      FileReader fr = new FileReader(f);
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }


  
}

Unchecked exceptions

We can also call them runtime exceptions since it occurs during the execution of the program. It is very important for the developer to handle these to exit safely from the code execution when it encounters an unexpected condition. Example: ArrayIndexOutOfBoundException, NullPointerException, etc.

Example

This is the most common example of unchecked exception where we try to divide a number by 0 which is actually not feasible. Runtime exceptions actually compile the code successfully and throw an exception during execution. Since we have not handled the exception in the code, we can see that the program execution terminates in the statement int result = a/0 and does not execute the remaining statements.

public class UncheckedException {
  
  int a = 5;
  
  public void divide() {
    int result = a/0;
    System.out.println(result);
    System.out.println("Divide method executed");
  }

  public static void main(String[] args) {
    UncheckedException uce = new UncheckedException();
    uce.divide();

  }

}
Exception in thread "main" java.lang.ArithmeticException: / by zero
  at UncheckedException.divide(UncheckedException.java:7)
  at UncheckedException.main(UncheckedException.java:13)

Handling the exception

We can implement unchecked exception handling either using throws or try-catch blocks. In the below example we have used a try-catch block where we write the code that might produce an exception inside the try block and write the message inside the catch block. Now, when we execute the code, it successfully handles the exception and prints the message. Also, it executes the remaining statements in the code. If you notice, it did not execute the last print statement “Divide method executed” when we did not handle the exception.

public class UncheckedException {
  
  int a = 5;
  
  public void divide() {
    try {
      int result = a/0;
      System.out.println(result);
    }
    catch(ArithmeticException e) {
      System.out.println("Division by 0 is not allowed");
    }
    System.out.println("Divide method executed");
  }

  public static void main(String[] args) {
    UncheckedException uce = new UncheckedException();
    uce.divide();

  }

}
Division by 0 is not allowed
Divide method executed

Java Exception methods

Below are the common methods that we use during exception handling in java. The examples of these methods are based on the above example of UncheckedException.

MethodDescriptionExample
public String getMessage()Returns the detailed exception message of the Throwable instance./ by zero
public String getCause()Returns the cause of the Throwable instance if known, else returns nullnull
public void printStackTrace()Prints the Throwable instance and its backtrace to the standard error stream.java.lang.ArithmeticException: / by zero
at UncheckedException.divide(UncheckedException.java:8)
at UncheckedException.main(UncheckedException.java:21)
public String toString()Returns the classname of the exception followed by the exception messagejava.lang.ArithmeticException: / by zero

Java Exception Keywords

To implement exception handling in Java, we use either of the below 5 keywords in our code.

Exception keywordDescription
tryContains the code in which exception might occur. It always precedes the catch block
catchContains the code to handle the exception. It prints the exception message. It always follows the try block
finallyIt is followed by the try block and handles the important code which needs to be executed irrespective of exception occurs or not
throwsIt is used to declare exceptions in the method signature. Specifies the type of exception that the method handles.
throwIt is used to throw an exception

Simple Exception Handling example

Below is a simple example that illustrates exception handling in java. We declare an array of integers variable numbers and initialize with 4 values. Hence the array size is 4 with index ranging from 0 to 3. Inside arrayElements method, we print the array index value 4 within the try block and handle the ArrayIndexOutOfBoundsException in the catch block. In the finally block, we just print a statement.  Now when we execute this code, it successfully handles the exception and prints the error message along with the statement in the finally block. It executes this block irrespective of whether an exception occurs or not.

public class ArrayException {

  int[] numbers = {5,8,1,3};
  public void arrayElements() {
    try {
      System.out.println("Element at index 4: " + numbers[4]);	
    }
    catch(ArrayIndexOutOfBoundsException e) {
      System.out.println(e.getMessage());
      System.out.println("Element at specified index does not exist");
    }
    finally {
      System.out.println("Handling Array Exceptions");
    }
  }
  public static void main(String[] args) {
    ArrayException a  = new ArrayException();
    a.arrayElements();

  }

}
Index 4 out of bounds for length 4
Element at specified index does not exist
Handling Array Exceptions

 

Reference

Translate »