by Dinesh Thakur

Exception handling in Java is accomplished by using five keywords: try, catch, throw, throws and finally.

In Java, the code that may generate (or throw) an exception is enclosed in a try block. The try block can be followed immediately by one or more catch blocks with a finally block as the last block. The try block can also end without a catch block, and the catch blocks need not always have finally as the last block.

Each catch block specifies the type of exception it can catch and contains an exception handler    code. After the last catch block, an optional finally block provides code that is always executed regardless of whether or not an exception occurs. If there are no catch blocks following a try block, the finally block is required.


When an exception is thrown, program control goes out of the try block and the catch blocks are searched in the order described earlier for an appropriate handler. If the exception type thrown matches the parameter type in one of the catch blocks, the code for that catch block is executed. If no exceptions are thrown in the try block, the exception handlers (catch blocks) for that block are skipped and the program resumes execution after the last catch block. If a finally block appears after the last catch block, it is executed, whether or not an exception is thrown.

We can specify with a throws clause the exceptions a method throws. An exception can be thrown from statements in the method or from a method that is called directly or indirectly from the try block. The point at which the throw is executed is called the throw point.

The Java statements that deal with exception handling are described in the following sections. The general syntax of try- catch-finally statement is as shown below:

try

{

  //java statements capable of throwing exceptions

}

catch (Exception_1 e)

{

  //java statements to handle the exception Exception_1

}

finally

{

//cleanup code or exit code (optional)

}

 Try block

The statements in a program that may raise exception(s) are placed within a try block. A try block is a group of Java statements, enclosed within braces { }, which are to be checked for exceptions. A try block starts with the keyword try.

To handle a run-time error and monitor the results, we simply enclose the code inside a try block. If an exception occurs within the try block, it is handled by the appropriate exception handler (catch block) associated with the try block. If there are no exceptions to be thrown, then try will return the result of executing the block. A try block should have one (or more) catch block(s) or one finally block or both. If neither is present, a compiler error occurs which says 'try' without 'catch' or 'finally'.

Exception handlers are put in association with a try block by providing one (or more) catch block(s) directly after the try block.

Catch block

A catch block is a group of Java statements, enclosed in braces { } which are used to handle a specific exception that has been thrown. catch blocks (or handlers) should be placed after the try block. That is, a catch clause follows immediately after the try block.

When an exception occurs in a try block, program control is transferred to the appropriate catch block. This transfer of control is unconditional, in the sense that the control will not return to the statement just after the throw point in the try block.

A catch block is specified by the keyword catch followed by a single argument within parentheses ( ). The argument type in a catch clause is from the Throwable class or one of its sub-classes. Java initializes the argument (parameter) to refer to the caught object. Program illustrates the use of the try-catch statements.

 

Program Using the try-catch statements.

 

public class Divide

{

   public static void main (String [] args)

   {

      System.out.println ("\n Program Execution starts here\n");

     int a, b, c;

      try

     {

       a = Integer.parselnt (args [0]);

       b = Integer.parselnt (args [1]);

       c = a/b;

       System.out.println (a + "I" + b + "=" + c);

    }

catch (Exception e)

{

   System.out.println (e);

}

  System.out.println ("\n Program Execution completes here");

   }

}

The output of the above program is as follows:

C:\javatest>java Divide 4 2

Program Execution starts here

4/2= 2

Program Execution completes here

C:\javatest>java Divide a 1

Program Execution starts here

java.lang.NumberFormatException: a

Program Execution completes here

C:\javatest>java Divide 4 0

Program Execution starts here

java.lang.ArithmeticException:/by zero

Program Execution completes here

C:\javatest>java Divide 4

Program Execution starts here

java.lang.ArraylndexOutOfBoundsException

Program Execution completes here

C:\javatest>

           

Once the code in the catch block is completely executed, program control is passed to the executable statement immediately following the catch block, which is a print statement, in the above example.

Note that while writing multiple catch statements, super-class exception types should follow the sub-class exception types, otherwise the unreachable code exception will arise during compile time.

Finally block

The final step in setting up an exception handler is providing a mechanism for cleaning up the program before control is passed to different part of the program. This can be achieved by enclosing the clean-up logic within the finally block. This is described in the following way.

The code within the finally block is always executed regardless of what happens within the try block. That is, if no exceptions are thrown, then no part of the code in the catch blocks is executed but the code in the finally block is executed.

If an exception is thrown, first the code in the corresponding catch block (exception handler) is executed and then the control is passed to the finally block and the code in the finally block is executed. Note that there is only one finally block per one try block. Program illustrates the use of the try-catch-finally statements .

• Program Using the try-catch-finally statements.

public class Divide

{

    public static void main(String[] args)

   {

       System.out.println("\n Program Execution starts here\n");

       int a, b, c;

       try

      {

          a = Integer.parselnt(args[O]);

          b = Integer.parselnt(args[1]);

          c = a/b;

          System.out.println( a + "/" + b + "=" + c);

      }

      catch(Exception e)

     {

         System.out.println( e);

     }

     finally

    {

        System.out.println{"Finally blocks always get executed");

    }

        System.out.println("\n Program Execution completes here");

   }

}

The output of Program is given below:

C:\javatest>java Divide 4 2

Program Execution starts here

4/2 = 2

Finally blocks always get executed

Program Execution completes here

C:\javatest>java Divide 4 0   

Program Execution starts here

java.lang.ArithmeticException: / by zero

Finally blocks always get executed

Program Execution completes here

C:\javatest>

Generally the finally block is used to close the files that have been opened, connections to the databases that have been opened, sockets in the networks that have been opened or for releasing any system resources. Note that if the code in the catch block terminates the program by executing System.exit (0), the code in the finally block will not be executed.

In the above code listing, a temporary file is created in the try block and the block also has some code that can potentially throw an exception. Irrespective of whether the try block succeeds, the temporary file has to be closed and deleted from the file system. This is accomplished by closing and deleting the file in the finally block.

Multiple catch blocks

Java allows having multiple catch blocks with one try block. Program illustrates the use of multiple catch blocks associated with a single try block.

 

Program Using multiple catch blocks.

public class Divide

{

    public static void main(String[ ] args)

   {

       System.out.println("\n Program Execution starts here\n");

      int a, b, c;

       try

      {

          a = Integer.parselnt (args[0]);

          b = Integer.parselnt (args[1]);

          c = a/b;

          System.out.println( a + "I" + b + "=" + c);

      }

      catch(NumberFormatException e)

     {

        System.out.println("Arguments passed should be valid Numbers");

     }

       catch(ArithmeticException e)

       {

          System.out.println("Second Argument Should not be Zero");

       }

       catch(ArrayIndexOutOfBoundsException e)

      {

         System.out.println("Pass Proper Arguments");

      }

         System.out.println("\n Program Execution Completes here");

   }

}

To see how Program responds to different inputs, the reader can run the program by giving inputs such as (4, 2), (4, a), (4, 0) etc.

When an exception occurs in the try block, the catch clauses are checked sequentially. A catch clause catches the exception if the thrown object is an instance of the type that is specified in the catch clause.

When multiple statements in a single try block throw different exceptions, different catch blocks must be written, one for each type of exception. On the other hand, each statement that might throw exception can be put into different try-catch blocks. Alternately, a single catch block can be defined as its parameter type, which is a super-class of all the exceptions that are to be handled. In some way, we have to identify particular exceptions and catch them within the catch block. This can be achieved by using the instance of operator as shown in the following example:

catch (Exception e)

{

   if (e instance of ArithmeticException)

  {

     ……..

  }

  else

  {

    If (e instance of NumberFormatException)

    {

      …….

     }

    else

    ……

    ……

  }

}

If a single statement throws multiple exceptions, it is better to have multiple catch blocks associated with the try block.

The order of catch blocks is very important when there are multiple catch blocks.

Nested try statements

The try statement can be nested. That is, one try statement can be placed inside the block of another try. Each time a try statement is entered, the context of that exception is pushed on the stack. If an inner try statement does not have a catch handler for a particular exception, the stack is unwound and the catch handlers belonging to the next try statement are inspected for a match. This continues until one of the catch statements succeeds, or until all the nested try statements are exhausted. If no catch statement matches, then the Java run-time system will handle the exception. In Program a pair of nested try statements have been used .

Program Using nested try-catch statements.

public class Divide

{

     public static void main(String[] args)

    {

        System.out.println("\n Program Execution starts here\n");

       int a, b, c;

        try

       {

           a = Integer.parselnt (args [0]);

           b = Integer.parselnt (args [1]);

           try

          {

             c = a/b;

             System.out.println( a + "I" + b + "=" + c);

          }

          catch(ArithmeticException e)

          {

              System.out.println("Second Argument Should not be Zero");

          }

         ////

       }

        catch(NumberFormatException e)

       {

          System.out.println("Arguments passed should be valid Numbers");

       }

       catch(ArraylndexOutOfBoundsException e)

      {

         System.out.println("Pass Proper Arguments");

      }

         System.out.println("\n Program Execution Completes here");

     }

}

The keyword throw 

An exception can be caught only if it is identified, or, in other words, thrown. Exceptions can be thrown by the Java run-time system for the code that has been written. This can be achieved also by using the throw statement explicitly.

This statement starts with the keyword throw followed by a single argument. The argument must be an object instantiated from the Throwable class or its sub-class. The syntax for using the throw statement is the following:

                         

throw <Exception object>

In a specific case where an instance of 'Exception object' is to be thrown, it takes the following form:

throw new <Exception object>

Usually the above statement is used to pass a string argument along with the exceptional object, so that the string can be displayed when the exception is handled.

Example

throw new IndexOutOfBoundsException ("Index out of range");

The throw statement is generally written with a conditional statement such as an if statement and switch statement. It is more useful when it comes to throwing user-defined exceptions which cannot be recognized by the Java run-time system.

Program illustrates the use of conditional statements:

ProgramUsing throw keyword.

public class Test Throw

{

    public static void main (String args [ ]) throws Exception

   {

       int number1 = 15, number2 = 10;

       if (number1 > number2) II Conditional statement.

       throw new Exception (number1 is 15");

      else

      System.out.println ("number2 is 15");

   }

}

The output of Program is

Exception in thread "main" java.Exception: number1 is 15

at Test Throw.main (Test Throw.java:8)

In Program the keyword throw is used to throw an exception with the message. With throw, the programmer is allowed to throw the exception and the system prints the messages and terminates the program.