Exception Handling in Java

In this post, you will learn to:

  • State the use of try-catch block.
  • Describe the use of finally block.
  • State the flow of execution in an exception handling block.
  • Describe the use of throw and throws keyword.
  • Describe the use of multiple catch blocks

Using the ‘try-catch’ Block

Java supports exception handling mechanism. The code that raises exceptions can be enclosed in a try block enabling the adjoining catch block to handle the raised exception. In addition, Java provides methods for reporting the cause of exception. Handling of exception involves logging the information on the exception and deciding whether to abort or continue execution of the statements succeeding the try-catch block.

The type of argument that the catch block will handle is determined by its argument. The type represents an Exception class that must be derived from the Throwable class. The code in the catch block will be executed only when exception of that type is invoked, otherwise the control passes to the statement following the try block. The following is the syntax to declare a try-catch block.

try {
   statement1;
   statement2; 
} catch (ExceptionType objectName1) {
  }

The following code demonstrates the use of try-catch block.

// Exception handling mechanism
try{
    // The following statement within try block will raise divide-by-zero, 
    // a type of ArithmeticException exception 
    System.out.println(1/0);
}

// Exception handler method; ArithmeticException is exception type 
catch (ArithmeticException e){
    System.out.println("This operation cannot be carried out");
    // method printStackTrace() prints detailed information about the 
    //exception
    e.printStackTrace();
)

Using the ‘finally’ Block

In case of an unexpected exception, the program exits without executing the remaining part of the code, giving rise to undesirable situations. For example, during file read operation if the file read operation fails due to unexpected exception, the file remains open. There is a chance of the file getting corrupted. Thus,the finally block is used along with the try-catch block. Using the catch block with try-finally is optional. The finally block will always be executed, even if an unexpected exception occurs. The cleanup code is placed inside a finally block, such as closing the files in file read operation.

The following is the syntax to declare the finally block.

try{
   // May raise expected/unexpected exception(s)
   Statement1;
   Statement2;
}

// catch block optional
catch(ExceptionB eb){
   // Handler Code
   Statement1;
   }

finally{
   //clean up code
   Statement1;
}

The following code shows the use of finally block.

finally {
    // file object out
    if (out != null) { 
        System.out.println("Closing file");
        out.close(); 
    } else { 
          System.out.println("file not open");
    } 
}

Execution Flow in case of Exception

Consider the following code snippet without a try-catch block:

int i=10,j=0; //1
System.out.println("i/j="+ i/j); //2
int k=i+10; //3

Line number 3 is never executed as the division of the integer by 0 in line number 2 will result in throwing of an exception by the runtime system. Consequently, an Exception object will be created. However, there is no exception handling mechanism in the code. Therefore, the exception will be handled by the default handler of JVM. The default handler will print a message providing the exception object name and its stack trace from the point where the exception occurred. Finally, it terminates the program.

Stack trace

The stack trace shows the sequence of method invocations that led up to the exception.

Exception object:

A Java exception is an object that describes an abnormal condition occurring in a part of code. The description contains information on error type and the state of the program. When an exception occurs in a method, an object representing that exception is created by the method and handed over to the runtime system.

Throw exception:

Creating an exception object and handing it to the runtime system is called throwing an exception.

Execution Flow with ‘try-catch’ Blocks

Java provides try-catch block to handle an exception. The following code discusses earlier lines of code and encloses it in try-catch block.

int i=10,j=0;
try{
   System.out.println("i/j="+ i/j);
   }
   catch(ArithmeticException e){
      System.out.println("Exception Caught"+ e.getMessage());
   }
int k=i+10;

In the example, the catch block with argument ArithmeticException handles the Exception object, the execution control flows to the catch block from the try block, and a message is printed with information on the exception object. Finally, it flows to the last line.

Call stack:

When a method throws an exception, the runtime system tries to find an appropriate method to handle it starting from the method that caused the exception. In this process, the system invokes a set of methods. The list of invoked methods that is called by the runtime system to reach to the method where the exception occurred is known as the call stack.

Exception handler:

The runtime system searches the call stack for a method that contains a piece of code that is able to handle the exception. This piece of code is called an exception handler.

Catching an exception:

When an appropriate exception handler matching an exception object is found, then it is known as catching an exception.

Execution Flow of Exception

If the last line needs to be always executed even if unexpected exception occurs, then it has to be placed inside a finally block along with try-catch block. The following code demonstrates the finally block to place code that needs to be always executed.

int i=10,j=0;
try{
      System.out.println("i/j="+ i/j);
   }
   catch(ArithmeticException e){
      System.out.println("Exception Caught"+ e.getMessage());
   }
   finally {
      int k=i+10;
 }

In the example, an Exception object is thrown in the try block that is handled in the catch block, because the exception object matches its argument, ArithmeticException. Next, the control passes to the finally block and the statement in it is executed, and lastly the control passes to the statement following the finally block.

Using ‘throw’ and ‘throws’ Keywords

The throws keyword indicates that a method might throw the declared exception during its execution. The throw keyword is used to manually throw an exception after performing some validation in a program. After the throw keyword is encountered, the flow of execution is altered and the subsequent statements are not executed. The exception generated by the throw statement is then propagated to the previous calling method on the call stack.

The throw statement requires a single argument: a Throwable object that is an instance of the Throwable class. Sometimes, a method can throw more than one exception. A comma-separated list of all exceptions thrown by a method is given with the method declaration. The throws keyword is used by the method to raise any checked or unchecked exception that it does not handle and enables the caller of the method to guard themselves against exception.

More than one exceptions can be listed with the throws clause and are separated by a comma. Except for Error or RuntimeException and their subclasses, the throws clause is necessary for all exceptions.

The following is the syntax of throw keyword to manually throw an exception.

throw throwableObject;

The following code demonstrates the use of throw keyword.

public class CalculatePrice {
   float price;
   void setPrice(float itemPrice) throws ArithmeticException {
        if (itemPrice<0.0) throw new ArithmeticException();
        price=itemPrice;
    }
}

If a negative value has been entered, the method setPrice throws an exception.

Output:

java.lang.ArithmeticException
  at CalculatePrice.setPrice(CalculatePrice.java:33)
   CalculatePrice.main(CalculatePrice.java:41)

Using Multiple ‘catch’ Blocks

A try block can have multiple catch blocks. This is required when the code in the try block can raise multiple exceptions. In such cases, multiple catch blocks containing different exception types are provided. When an exception is raised, each catch block is inspected one at a time until a matching block is found. Once a match is found, the remaining catch blocks are ignored, and execution proceeds after the last catch block.

When multiple catch blocks are used, catch blocks with exception subclasses must be placed before the superclasses, otherwise, the superclass exception will catch exceptions of the same class and its subclasses. Consequently, catch blocks with exception subclasses will never be reached.

The following is the syntax to declare multiple catch blocks.

try {
 
} catch (ExceptionType name) {
 
} catch (ExceptionType name) {
 
}

The following code demonstrates the use of multiple catch blocks.

try {
// potential exception generator statements 
} 

// First catch block 
catch (FileNotFoundException e) {
    System.out.println("Caught FileNotFoundException: " + e.getMessage()); 
} 

// Second catch block
catch (IOException e) {
    System.out.println("Caught IOException: " + e.getMessage());
}
catch (Exception e) {
    System.out.println("Caught Exception: " + e.getMessage());
}
Note: As a good practice, always place catch blocks with exception subclasses first and the base class of all exceptions, Exception at the end. Otherwise, catch blocks with subclass exceptions will be unreachable and, during compile time, display unreachable code error.
Related Post