11 Exception Handling

11.1 INTRODUCTION

In Java, errors can be divided into two categories: compile time errors and runtime errors. Compile time errors are syntactic errors during writing of the program. Most common examples of compile time errors are missing semicolon, comma, double quotes, etc. They occur mainly due to poor understanding of language or lack of concentration in writing the program.

Logical errors occur mainly due to improper understanding of the program logic by the programmer. Logical errors cause the unexpected or unwanted output.

Exceptions are runtime errors which a programmer usually does not expect. They occur accidentally, which may result in abnormal termination of the program. Java provides exception handling mechanism, which can be used to trap this exception and run programs smoothly after catching the exception.

Common examples of exceptions are division zero, opening file which does not exist, insufficient memory, violating array bounds, etc.

11.2 WHAT IS EXCEPTION?

Exception can be defined as follows: "An exception is an event that occurs during the execution of a program, which disrupts the normal flow of the program's instructions".

When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.

images

Figure 11.1 The call stack

After a method throws an exception, the runtime system attempts to find something to handle it. The set of possible 'somethings' to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred. The list of methods is known as the call stack (Figure 11.1).

The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.

The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, as shown in Figure 11.2, the runtime system (and, consequently, the program) terminates.

images

Figure 11.2 Searching the call stack for the exception handler

11.3 BASIS FOR EXCEPTION HANDLING

A program is correct if it accomplishes the task it was designed to perform. It is robust if it can handle illegal inputs and other unexpected situations in a reasonable way. For example, consider a program that is designed to read some numbers from the user and then print the same numbers in sorted order. The program is correct if it works for any set of input numbers. It is robust if it can also deal with non-numeric input by, for example, printing an error message and ignoring the bad input. A non-robust program might crash or give nonsensical output in the same circumstance.

Getting a program to work under ideal circumstances is usually a lot easier than making the program robust. A robust program can survive unusual or 'exceptional' circumstances without crashing. One approach to writing robust programs is to anticipate the problems that might arise and to handle tests in the program for each possible problem. For example, a program will crash if it tries to use an array element ARR[i], when 'i' is not within the declared range of indices for the array ARR. A robust program must anticipate the possibility of a bad index and guard against it. This could be done with an if statement.

if(i<0||i>=ARR.length)
{
   ......//Do something to handle the out-of-range index, i
}
else
{
   ......//Process the array element, ARR[i]
}

There are some problems with this approach. It is difficult and sometimes impossible to anticipate all the possible things that might go wrong. It is not always clear what to do when an error is detected. Furthermore, trying to anticipate all the possible problems can turn what would otherwise be a straightforward program into a messy tangle of if statement.

Java provides a neater, more structured alternative method for dealing with errors that can occur while a program is running. The method is referred to as exception handling. The word 'exception' is meant to be more general than 'error'. It includes any circumstance that arises as the program is executed, which is meant to be treated as an exception to the normal flow of control of the program. Exception handling is the process to handle the exception if generated by the program at run time. The aim of exception handling is to write a code which passes exception generated by the program at run time. The aim of exception handling is to write a code which passes exception generated to a routine which can handle the exception and can take suitable action.

11.4 EXCEPTION-HANDLING MECHANISM

In Java, exceptions are objects which are thrown. All such codes which might throw an exception during the execution of the program must be placed in the try block. The usage of try block has been observed in a number of programs earlier. The exception thrown must be caught by the catch block. If not caught, the particular program may terminate abnormally. An exception can be thrown explicitly or implicitly. Exception can be explicitly thrown using the keyword throw. In explicit exception, a method must tell what type of exception it might throw. This can be done by using the throw keyword. All the other exceptions thrown by the Java runtime system are known as implicit exceptions. A final clause may be put after the try-catch block, which executes before the method returns. A try block must have a corresponding catch block, though it may have a number of catch blocks.

This try block is also known as exception-generated block or guarded region. The catch block is responsible for catching the exception thrown by the try block. It is also known as exception handler block. When the try block throws an exception, the control of the program passes to the catch block, and if argument matches, the exception is caught. In case no exception is thrown, the catch block is ignored and control passes to the next statement after the catch block.

The general syntax of exception-handling construct is shown as follows:

try
{
statements;
statements;
statements;
}
catch(Exceptionclass1 object)
{
   statements for handling the exception;
}
catch(Exceptionclass1 object)
{
   statements for handling the exception;
}
...........
finally
{
   //statements executed before method returns
}

11.5 EXCEPTION CLASSES IN JAVA

In Java, exceptions are objects. When you throw an exception, you throw an object. You cannot throw just any object as an exception. The exception class hierarchy is shown in Figure 11.3. All exception class are defined in the package java.lang, which is default imported in all Java programs.

package java.lang;

images

Figure 11.3 Exception class hierarchy in Java

The top most exception class is the throwable class. Throwable serves as the base class for an entire family of classes, declared an entire family of classes, declared in java.lang, that a particular program can instantiate and throw. As can be seen in Figure 11.3, Throwable has two direct subclasses, Exception and Error.Exceptions (members of the Exception family) are thrown to signal abnormal conditions that can often be handled by some catch block although it is possible they may not be caught and, therefore, could result in a dead thread. Exception class is also used when generated exceptions are needed to be thrown. For that Exception class will be made as the base class.Errors (members of the Error family) are usually thrown for more serious problems, such as OutOfMemoryError, that may not be so easy to handle. In general, the code that is written should throw only exceptions, not errors. Errors are usually thrown by the methods of the Java API or by the Java virtual machine itself.

11.5.1 Runtime Exception

There is a whole group of exception types in this category. They are always thrown automatically by Java and one does not need to include them in exception specifications. Conveniently enough, they are all grouped together under a single base class called RunTimeException. It establishes a family of types that have some characteristics and behaviours in common. Also, one never needs to write an exception specification because a method might throw a RunTimeException. Because they indicate bugs, RunTimeException is not usually caught; it is dealt with automatically. Even though RunTimeExceptions are not caught typically, in one's own packages some of the RunTimeExceptions might be chosen to throw. Some of the examples or exceptions which come under this RunTimeException class are division by zero, array and string index out of bound, casting a class, illegal format exception, etc.

11.5.2 Checked versus Unchecked Exception

There are two kinds of exceptions in Java: checked and unchecked. Only checked exceptions need appear in throws clauses. The general rule is: any checked exceptions that may be thrown in a method must either be caught or declared in the method's throws clause . Checked exceptions are so called because both the Java compiler and Java virtual machine check to make sure this rule is obeyed.

Whether or not an exception is 'checked', is determined by its position in the hierarchy of Throwable classes. Figure 11.4 shows that some parts of the Throwable family tree contain checked exceptions while other parts contain unchecked exceptions. To create a new checked exception, another checked exception is simply extended. All Throwables that are subclasses of Exception , but not subclasses of RuntimeException are checked exceptions.

images

Figure 11.4 Checked and unchecked exception

All the checked and unchecked exceptions defined by Java are given in Tables 11.1 and 11.2.

Exception Class Reason of Occurrence
ArithmeticException Arithmetic error, such as divide by zero
ArrayIndexOutOfBoundsException Array index if out-of-bounds
ArrayStoreException Assignment to an array element of an incompatible type
ClassCastException Invalid cast
IllegalArgumentException Illegal argument used to invoke a method
IllegalMonitorStateException Illegal monitor operation, such as waiting on an unlocked thread
IllegalStateException Environment or application is in incorrect state
IllegalThreadStateException Requested operation not compatible with current thread state
IndexOutOfBoundsException Some type of index is out-of-bound
NegativeArraySizeException Array created with a negative size
NullPointerException Invalid use of a null reference
NumberFormatException Invalid conversion of a string to a numeric format
SecurityException Attempt to violate security
StringIndexOutOfBounds Attempt to index outside the bounds of string
UnsupportedOperationException An unsupported operation was encountered

Table 11.1 Java's unchecked runtime exception subclasses

Exception Class Reason of Occurrence
ClassNotFoundException Class not found.
CloneNotSupportedException Attempt to clone an object that does not implement the cloneable interface.
IllegalAccessException Access to a class is denied.
InstantiationException Attempt to create an object of an abstract class or interface.
InterruptedException
NoSuchFieldException
One thread has been interrupted by another thread.
One thread has been interrupted by another thread
NoSuchMethodException A requested method does not exist.

Table 11.2 Java's checked exceptions defined in java.lang

11.6 WITHOUT TRY-CATCH

Before dealing with the exception and handling them, it will be seen in the absence of try-catch block, how exceptions are thrown by the runtime system and how they are handled.

Consider the following program given below:

/*PROG 11.1 WITHOUT TRY-CATCH BLOCK */
class JPS1
{
   public static void main(String[]args)
   {
          String str = "Exception";
          int x = str.charAt(str.length()+1);
          System.out.println("Control won't reach here");
   }
}

OUTPUT:

Exception in thread "main"
java.lang.StringIndexOutOfBoundsException: String index out
of range: 10
          at java.lang.String.charAt(String.java:687)
          at JPS1.main(JPS1.java:6)

Explanation: In the program, an index is tried to be accessed from a String str which is out of bound; therefore, this causes an exception to be thrown.

When the Java runtime system sees the string index is out of bound, it constructs a new exception object and throws it. The exception thrown must be caught, but there is no catch block here for catching the exception, so exception thrown results in terminating the program prematurely. In the absence of try-catch block, the default exception handler of the Java runtime system handles the exception, but at the cost of terminating the program abnormally.

Note the output of the program, the default handler returns a string which shows where the exception occurred in the program, what type of exception it was and the precise reason for the generation of exception. The last line of the output shows in which method or subroutine the exception was generated. The output is actually a stack trace, i.e., examining the system stack which was storing what went wrong. The stack trace shows all the methods in sequence that tells us the error in string form.

A stack trace provides information on the execution history of the current thread, and lists the names of the classes and methods that were called at the point when the exception occurred. A stack trace is a useful debugging tool that can be made use of when an exception has been thrown.

11.7 EXCEPTION HANDLING USING TRY AND CATCH

This section presents how programmatically exceptions are thrown within try block and handled by the catch block. To begin with the first program on exception handling is given below.

/*PROG 11.2 DEMO OF EXCEPTION HANDLING EXCEPTION IN CONVERSION */
import java.lang.*;
class main
{
   public static void main(String args[])
   {
         try
         {
                int num;
                num=Integer.parseInt("ABC123");
                System.out.println("Control won't reach
                                                  here");
         }
         catch(NumberFormatException E)
         {
                System.out.println("Exception thrown");
                System.out.println(E.getMessage());
         }
         System.out.println("Out of try-catch block");
   }
}

OUTPUT:

Exception thrown
For input string: "ABC123"
Out of try-catch block

Explanation: In the try block, a string is converted into integer. The string contains some alphabets along with digits. If the string were having just the digits, the conversion from string to integer was possible. But as it contains alphabets, conversion would not be allowed and an exception object of class type NumberFormatException will be thrown from try block. This object thrown will be caught by the catch block in the object E, which is also of NumberFormatException class, so a match will be found. The getMessage method defined in the Exception can be used to display the internally generated message. The second line of output is internally generated message returned as String from getMessage().

/*PROG 11.3 DEMO OF EXCEPTION HANDLING ACCESSING ARRAY INDEX OUT OF RANGE */
import java.lang.*;
class JPS3
{
   public static void main(String [] args)
   {
          try
          {
                 int[]num = {0,1,2,3,4};
                 int x = 25/num[5];
                 System.out.println("Control won't reach
                                                  here");
          }
          catch(ArrayIndexOutOfBoundsException E)
          {
                 System.out.println("Exception thrown");
                 E.printStackTrace();
          }
   }
}

OUTPUT:

Exception thrown
java.lang.ArrayIndexOutOfBoundsException: 5
          at JPS3.main(JPS3.java:10)

Explanation: In the try block, an array element is accessed, the index of which is out of bound. So try block throws an exception object of type ArrayIndexOutOfBoundsException. This exception object thrown is caught by the catch block in the object E. Using this object E, the stack trace is displayed by a call to printStackTrace method. The output is due to printStackTrace method, which clearly indicates types and exception occurred, and place and the line number.

1. Try with multiple catch : Sometimes it is possible that a single try block may throw exceptions of different types at run time. If any of the exception is not handled that might be thrown, a premature termination of the program occurs. To catch all such types of exception, one catch block can be placed per exception that might be generated within the try block. Depending on what type of exception thrown, corresponding catch blocks catches the exception object thrown by the try block. The general syntax is as follows:

Here, if the exception object thrown is of ExceptionClass1 type, the first catch block will catch the exception object thrown and the remaining catch blocks will be bypassed. In case, the exception object thrown does not match with the first catch block, the second catch block is tried and so on. At a time only one catch block will be used. It is also possible sometimes that ExceptionClass1 is a base class of ExceptionClass2 or/and ExceptionClass3, then any exception object thrown of a type ExceptionClass1 and ExceptionClass2 and/or ExceptionClass3 will be caught by ExceptionClass1.

/*PROG 11.4 TRY WITH MULTIPLE CATCH BLOCK VER 1 */
import java.io.*;
class JPS4
{
   public static void main(String[]args)
   {
          PrintStream cout = System.out;
          try
          {
                DataInputStream input;
                input = new DataInputStream(System.in);
                int n1, n2, ans = 0;
                cout.println("Enter first number");
                n1 = Integer.parseInt(input.readLine());
                cout.println("Enter second number");
                n2 = Integer.parseInt(input.readLine());
                ans = n1/n2;
                cout.println("This will be printed");
          }
          catch(ArithmeticException E)
          {
                cout.println("Exception thrown:");
                cout.println("Description:"+E);
          }
          catch(NumberFormatException E)
          {
                cout.println("Exception thrown:");
                cout.println("Description:"+E);
          }
          catch(IOException E)
          {
                cout.println("Exception thrown:");
                cout.println("Description:"+E);
          }
          cout.println("Out of try-catch block");
   }
}

OUTPUT:

(First Run)
Enter first number
12
Enter second number
5
This will be printed
Out of try-catch block
(Second Run)
Enter first number
12
Enter second number
0
Exception thrown:
Description:java.lang.ArithmeticException: / by zero
Out of try-catch block

(Third run)
Enter first number
46
Enter second number
4.5
Exception thrown:
Description:java.lang.NumberFormatException: For input
string: "4.5"
Out of try-catch block

Explanation: In the program within the try block, three different types of exceptions may be thrown: First, exceptions of the type ArithmeticException, which may be generated when division by zero operation is performed. Second, when instead of integer some other data types are input, like float, double, char or string or even just press Enter; exception of type NumberFormatException type is thrown. Third, when there is some error in reading input from keyboard or writing output onto the screen. This will not be generated on the user part, but this exception must be caught otherwise it will throw compilation error.

In the first run of the program, the division of the two numbers are simply obtained as output; no exception is generated. In the second run, when 0 is input for denominator, Java runtime system checks that division by zero operation is performed, which is an illegal operation, so it constructs an object of ArithemeticException type and throws it. This thrown exception is caught by the first catch block, which displays the description of the exception thrown. It should be noted that this time the object E is simply placed in cout.println method. Java interpreter automatically converts the exception object into String by calling the toString method. In the third run of the program, float is intentionally input. As the Integer.parseInt cannot parse float string into integer, an exception object of NumberFormatException class is generated and thrown. The thrown object is caught by the second catch block.

Note in all run after handling the exception by the catch blocks, statements after the try-catch block execute as if nothing has happened.

Whenever there are multiple catch statements, it is possible that one exception class in a catch block is a subclass or super class of another exception class placed in another catch block. In this scenario, if the Exception1 class in the first catch block is super class of the Exception2 class placed in the next catch block, all the exceptions thrown for the Exception2 class will be caught by the first catch block. In this case, second catch block will not be used in the program, thus generating compilation error. See the next program given below.

Note: The division by zero exception will not be thrown in case of data type float and double. You will get answer 'Infinity', and if you try to perform operation 0/0, you will get the output NaN, which means 0/0 is not a Number.

2. The throw keyword: In all the programs of exception handling seen earlier, the Java runtime system was responsible for throwing the exceptions. All those exceptions come under the category of implicit exceptions. If we want, we can throw exceptions manually or explicitly. For that, Java provides the keyword throw. The throw keyword can be used to throw an exception explicitly. It can be used to rethrow an exception which has already been thrown.

The throw statement requires a single argument: a throwable object. Throwable objects are instances of any subclass of the throwable class. Here is an example of a throw statement.

throw someThrowableObject;

The throw statement can be given in an example. The following pop method is taken from a class that implements a stack of integers. The method removes the top element from the stack and returns it.

public int pop()
{
   int obj;
   if(top ==o)
   {
   throw new EmptyStackException();
   }
   obj = arr[top--];
   return obj;
}

The pop method checks to see whether any elements are on the stack. If the stack is empty (top is equal to 0), pop instantiates a new EmptyStackException object (a member of java.util) and throws it. A user can throw only objects that inherit from the java.lang. Throwable class. See exception class hierarchy diagram.

As soon as the throw statement is encountered, the runtime system checks for a matching catch block which can accept an object to be thrown by the throw. If it can be handled, control is transferred to the catch block. If it does not match, the object is passed to the next catch block if present. In case no matching catch block is found, default Java runtime handler handles the exception by printing the stack trace.

/*PROG 11.6 DEMO OF THROW VER 1 */
class JPS6
{
   public static void main(String args[])
   {
          try
          {
                throw new ArithmeticException("Hello from
                                                 throw");
          }
          catch(ArithmeticException E)
          {
                System.out.println("Exception caught:
"+E);
                System.out.println(E.getMessage());
          }
   }
}

OUTPUT:

Exception caught:
java.lang.ArithmeticException: Hello from throw
Hello from throw

Explanation: In the program, an exception of type ArithmeticException is intentionally thrown using the constructor method which takes an argument of String type. The thrown exception object is caught by the catch block and stored in E. The E.getMessage() shows the String argument append along with the internally generated message.

3. Rethrowing an exception: Sometimes one might want to rethrow the exception just caught, particularly, when Exception is used to catch any exception. Since the reference to the current exception is already there, that reference can simply be rethrown:

catch(Exception e)
{
   System.out.println("An exception was thrown ");
   throw e;
}

Rethrowing an exception causes it to go to the exception handlers in the next higher context. Any further catch clauses for the same try block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object.

4. Catching any exception: It is possible to create a handler that catches any type of exception. It is done by catching the base-class type exception (there are other types of base exceptions, but Exception is the base that is pertinent to virtually all programming activities):

catch(Exception e)
{
   System.out.println("Caught an exception");
}

This will catch any exception, so if you use it, you will want to put it at the end of your list of handlers to avoid preempting any exception handlers that might otherwise follow it. Now one comes to know why this class has been used with catch blocks in some of the programs in other chapters.

/*PROG 11.8 CATCHING ALL EXCEPTION VER 1 */
class JPS8
{
   public static void main(String[]args)
   {
          int num = 10;
          for(num = 10;num<=30;num+=10)
          {
                 try
                 {
                        if(num == 20)
                        throw new ArithmeticException("Arithme
                                                  tic");
                         else if(num<20)
                           throw new RuntimeException("Run
                                                    time");
                           else if(num>20)
                           throw new NullPointerException("Null
                                                    Pointer");
                 }
                 catch(Exception E)
                 {
                         System.out.println("Caught an
                                             exception");
                         System.out.println(E.getMessage());
                 }
          }
   }
}

OUTPUT:

Caught an exception
Run time
Caught an exception
Arithmetic
Caught an exception
Null Pointer

Explanation: Since the Exception class is the base of all the exception classes that are important to the programmer, one does not get much specific information about the exception, but the method that comes from its base type throwable, can be called. One such method seen earlier is getMessage(), which returns a String containing the description of the exception object. Rest is self-explanatory.

/* PROG 11.9 CATCHING ALL EXCEPTION VER 2 */
class demo1 extends Exception
{
}
class demo2 extends Exception
{
}
class demo3 extends Exception
{
}
class JPS9
{
   public static void main(String[]args)
   {
          int num=10;
          for(num=10;num<=30;num+=10)
          {
                try
                {
                       if(num==20)
                       throw new demo1();
                       else if(num<20)
                       throw new demo2();
                       else if(num>20)
                       throw new demo3();
                }
                catch(Exception E)
                {
                        System.out.println("Caught an
                                            exception");
                }
          }
   }
}

OUTPUT:

Caught an exception
Caught an exception
Caught an exception

Explanation: Program is self-explanatory.

5. The throw clause: In Java, when a method does not handle all the exceptions it can throw , it must specify all such exceptions in the declaration of the method using throws clause. This is the exception specification and it is part of the method declaration, appearing after the argument list. The throws clause comprises the throws keyword followed by a comma-separated list of all the exceptions thrown by that method. All the exceptions which are not of type classes error or RuntimeException or any of their subclasses, must be specified. The clause goes after the method name and argument list and before the brace that defines the scope of the method; an example is shown below.

public void fun()throws IOException, Illegal AccessException

The above function fun declares that the function fun can throw exceptions of type IOException and IllegalAccessException type. The client of the method must write code to guard against these exceptions.

The general syntax is as follows:

access_specifier return_type method_name(parameterlist)throws
exceptionclass1,  exceptionclass2,...exceptionclassN
{
    //definition of the method
}

If the code within your method causes exceptions, but your method does not handle them, the compiler will detect this and will either tell that you must handle the exception or indicate with an exception specification that it may be thrown from your method. By enforcing exception specifications from top to bottom, Java guarantees that a certain level of exception correctness can be ensured at compile time.

One such example seen earlier is the function readLine which have been used in a number of programs. The function throws an exception of type IOException. The signature of the method is as shown below:

public final String readLine()throws IOException

So, if the Java code is written in the following way

import java.io.*;
class JPS1
{
   public static void main(String[]args)
   {
          String str;
          DataInputStream input;
          input = new DataInputStream(System.in);
          str = input.readLine();
   }
}

the program will not compile and the following error will be generated:

C:>javac JPS1.java
JPS1.java:9: unreported exception java.io.IOException; must be
caught or declared to be thrown
          str = input.readLine();
                                ^
Note: JPS1.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error

This error can be rectified in two ways: either specify the exception in the thrown clause or handle the exception using try catch block. Both are given below:

/* FIRST APPROACH */
import java.io.*;
class JPS
{
   public static void main(String args[])
   {
          try
          {
                 String str;
                 DataInputStream input;
                 input = new DataInputStream(System.in);
                 str = input.readLine();
          }
          catch(IOException E)
          {
                 System.out.println("Error:"+E);
          }
   }
}

OUTPUT:

C:>javac JPS2.java
Note: JPS2.java uses or overrides a deprecated API.
Note: Recompile with -Xlint: deprecation for details.
C:>java JPS2
Exception in thread "main" java.lang.NoClassDefFoundError:
JPS2
/* SECOND APPROACH */
import java.io.*;
class JPS3
{
   public static void main(String[]args)throws IOException
   {
          String str;
          DataInputStream input;
          input = new DataInputStream(System.in);
          str = input.readLine();
   }
}

Let us create our own method which throws an exception.

/*PROG 11.10 THROWING EXCEPTION FROM A METHOD */
import java.io.*;
class JPS10
{
   static void demo()throws IOException
   {
          throw new IOException("demo of throws");
   }
   public static void main(String args[])
   {
          try
          {
                demo();
          }
          catch (IOException E)
          {
                System.out.println("Exception Caught");
                System.out.println(E.getMessage());
          }
   }
}

OUTPUT:

Exception Caught
demo of throws

Explanation: The method demo declares using throws clause that it can throw an exception of IOException class type. In the main inside try block, the demo method is called. As the method can throw an exception, it is placed it in the try block. The method when called throws an exception of type IOException as follows:

new IOException("demo of throws");

The exception object thrown is caught by the catch block and the program terminates gracefully:

import java.io.*;
class JPS11
{
   static void demo() throws IOException
   {
          throw new IOException("demo of throw");
   }
   public static void main(String[] args)throws
   IOException
   {
          demo();
   }
}

Then the program will compile but will generate runtime error as follows:

C:JPSCh11>javac JPS11.java
C:JPSCh11>java JPS11
Exception in thread "main" java.io.IOException: demo of throw
    at JPS11.demo(JPS11.java:6)
    at JPS11.main(JPS11.java:10)

This is because the exception declared in the throw clause of demo function was not handled. Declaring the exception in the function main using throws clause can only prevent from compilation error but not from runtime error.

6. Nesting of try-catch block: Just like the multiple catch blocks, there can also be multiple try blocks. These try blocks may be written independently or can nest within each other, i.e., keep one try-catch block within another try block. The program structure for nested try statement is look like the following:

try
{
    //statements
    //statements
    try
    {
           //statements
           //statements
    }
    catch(<exception_two> obj)
    {
           //statements
    }
    //statements
    //staements
}
catch(<exception_two> obj)
{
//statements
}

The following example illustrates the above.

/*PROG 11.11 DEMO OF NESTED TRY-CATCH BLOCK */
class Nested_Try
{
   public static void main(String args[])
   {
          try
          {
                int a = Integer.parseInt(args[0]);
                int b = Integer.parseInt(args[1]);
                int quot = 0;
                try
                {
                       quot = a / b;
                       System.out.println(quot);
                }
                catch (ArithmeticException e)
                {
                       System.out.println("divide by
                                           zero");
                }
          }
          catch (NumberFormatException e)
          {
                System.out.println("Incorrect argument
                                           type");
          }
   }
}

The output of the program is as follows:

(i)   If the arguments are entered properly, like the following:

C:JPSCh11>java Nested_Try 24 6 4

(ii)  If the argument contains a string than the number or vice versa:

C:JPSCh11>java Nested_Try 24 bb
Incorrect argument type

(iii) If the second argument is entered zero:

C:JPSCh11>java Nested_Try 24 0 divide by zero

Explanation: In the program, two numbers are accepted from the command line. After that, the command line arguments which are in the string format, are converted to integers. If the numbers were not received properly in a number format, during the conversion a NumberFormatException is raised, otherwise the control goes to the next try block. Inside this second try-catch block, the first number is divided by the second number, and during the calculation if there is any arithmetic error, it is caught by the inner catch block.

7. The finally clause: There is often some piece of code that one wants to execute whether or not an exception is thrown within a try block. This usually pertains to some operation other than memory recovery (since that is taken care of by the garbage collector). To achieve this effect, a finally clause is used at the end of all the exception handlers. The syntax of try-catch -finally is presented here once again:

try
{
    //The guarded region:harmful activities
    //that might throw A, B or C.
}
catch(A a1)
{
    //Handler for argument
}
catch(B b1)
{
    //Handler for situation B
}
catch(C c1)
{
    //Handler for situation C
}
finally
{
    //Activities that happen every time
}

The finally clause, similar to catch and try, is a block of code by the name finally. The finally executes all the time irrespective of whether an exception is thrown or not. Even if an exception is thrown and handled or not, finally will execute. The finally block is guaranteed to execute after the try-catch block. The finally clause is an optional. and its usage is up to the programmer. If try-catch block is placed inside a method, before returning from the method, either maturely or prematurely, finally clause will execute. The finally clause is necessary in some kind of cleanup like an open file or network connection, something you have drawn on the screen, etc.

/*PROG 11.12 DEMO OF FINALLY, EXCEPTION CAUGHT */
class JPS12
{
   public static void main(String[] args)
   {
          try
          {
                throw new NullPointerException();
          }
          catch (NullPointerException E)
          {
                System.out.println("Exception Caught");
          }
          finally
          {
                System.out.println("Finally executes");
          }
   }
}

OUTPUT:

Exception Caught
Finally executes

Explanation: Program is simple; from within try block, an exception object of NullPointerException is thrown. This exception object is handled by the catch block. After that finally executes.

/*PROG 11.13 DEMO OF FINALLY, EXCEPTION NOT CAUGHT */
class JPS13
{
   public static void main(String[] args)
   {
          try
          {
                throw new NullPointerException();
          }
          finally
          {
                System.out.println("Finally excutes");
          }
   }
}

OUTPUT:

Finally excutes
Exception in thread "main" java.lang.NullPointerException at
JPS13.main(JPS13.java:8)

Explanation: The aim of the program is to simply show that whether or not an exception is thrown, finally block executes.

/*PROG 11.14 DEMO OF FINALLY RETURNING FROM METHOD */
class JPS14
{
   static void fun()
   {
          try
          {
                 return;
          }
          finally
          {
                 System.out.println("
Finally executes");
          }
   }
   public static void main(String[] args)
   {
          fun();
   }
}

OUTPUT:

Finally executes

Explanation: In the static function fun, only the try and finally block are written and not catch block. In the try block, we simply returned from the function. But note before returning from the function, the finally block executes and prints Finally executes.

11.8 CREATING YOUR OWN EXCEPTION

To create your own exception, you will need to make Exception or Throwable class as the base class of the class which you are going to create. We have seen that Throwable class is the top most class in the exception class hierarchy, so all the methods of Throwable class can be used by the derived class. Some of the methods of Throwable class you can use are as follows:

1.   String getMessage(): Returns the description of the exception object thrown.

2.   void printStackTrace(): Displays the stack trace.

3.   String toString(): Converts a class object into String object.

Even the methods can be overridden as per your requirement. Two programs are given below:

/*PROG 11.15 DEMO OF CREATING OUR OWN EXCEPTION VER 1 */
class demo extends Exception
{
   demo(String s)
   {
          super(s);
   }
}
class JPS15
{
   public static void main(String[] args)
   {
          try
          {
                throw new demo("
Hello from own
                                    exception");
          }
          catch (demo E)
          {
                System.out.println(E.getMessage());
          }
   }
}

OUTPUT:

Hello from own exception

Explanation: In the program, a class demo and extend class Exception are created. In the one argument constructor of String type, the argument to construct of super class is sent, i.e., Exception using super. In the main, the exception of demo class is thrown as throw new demo("Hello from exception");. The thrown object is caught by the catch block in object E. The E.getMessage displays the String argument of the object passed as argument.

/*PROG 11.16 DEMO OF CREATING OUR OWN EXCEPTION VER 2 */
class MyException extends Exception
{
   private int num;
   MyException(int a)
   {
          num = a;
   }
   public String toString()
   {
          return "MyException Thrown with num =" + num;
   }
}
class JPS16
{
   static void check(int x) throws MyException
   {
          System.out.println("
check called x =" + x);
          if (x < 0)
                 throw new MyException(x);
          System.out.println("Returning from function");
   }
   public static void main(String args[])
   {
          try
          {
                 check(10);
                 check(-10);
          }
          catch (MyException e)
          {
                 System.out.println("Exception caught " + e);
          }
   }
}

OUTPUT:

check called x =10
Returning from function
check called x =-10
Exception caught MyException Thrown with num =-10

Explanation: The MyException class has one int argument constructor which initializes the num. The function has toString method overridden, which is called automatically when displaying an object of MyException class to convert it into String form. In the main, when method check is called with negative argument, exception of MyException is thrown. This thrown exception is caught by the catch block in 'e', which is displayed. As object cannot be displayed in this manner, but as we have toString method defined in the MyException class, this method is called and string "MyException Thrown with num 5 210" is returned.

11.9 PONDERABLE POINTS

1.   Exception is a runtime error which may occur in the program.

2.   An exception if not handled may terminate the program abnormally.

3.   To deal with exceptions, try-catch blocks are used.

4.   An exception in programming term is considered an object which is thrown.

5.   Any program code or function which may generate exception is placed in the try block. The exception thrown is caught by catch block.

6.   Every try block must have the corresponding catch block or finally block. The exception thrown is caught by the catch block. If catch block is unable to handle the exception, the program may terminate prematurely.

7.   The root class of all exception class is the Throwable class.

8.   Checked exceptions are those exceptions which either must be caught or declared in the throw clause.

9.   For one try block, there may be multiple catch blocks.

10. The finally block executes regardless of an exception is thrown or not.

11. A function can specify what type of exception can be thrown by specifying in the function declaration using throws clause.

12. Objects of user-defined classes as exception can also be thrown.

13. The advantages of exceptions are as follows:

(a) Separating error-handling code from 'regular' code.

(b) Propagating errors up the call stack.

(c) Grouping and differentiating error types.

REVIEW QUESTIONS

1.   Explain how exception handling mechanism can be used in a program.

2.   How many catch blocks and finally blocks can we use with try block?

3.   How do you define try and catch block?

4.   What is unchecked and checked exception?

5.   Define an exception called "NoEqualExcep-tion" that is thrown when a float value is not equal to 3.14. Write a program that uses the above user defined exception.

6.   Write a method

private static String readExistingFilename()

That keeps reading String from the user until it receives the name of an existing file, then, returns that String.

7.   Write a program that reads the name of a file and computes the number of lines in the file that represent integers. Use Integer.parseInt to parse complete line read from the file. Use Java's Exception mechanism to detect when a given line is not a valid int.

8.   Can a try block have two finally block? Prove it.

9.   Can a catch follow a finally block? Prove it.

10. Does Java permit a try block to have two catch blocks for the exact same exception? Prove it.

11. Give code for which two catch blocks are triggered by the same exception. Prove that only the first catch block is executed.

12. Define an exception called "NoMatchException" that is thrown when a string is not equal to "India". Write a program that uses this exception.

13. Write a program to demonstrate the use of exception handling.

14. Write a program for user defined exception that checks the internal and external marks; if the internal marks is greater than 40 it raises the exception "Internal marks is exceed"; if the external marks is greater than 60 it raises the exception and displays the message "The External Marks is exceed". Create the above exception and use it in your program.

Multiple Choice Questions

1.   For one try block there may be

(a) only 1 catch block

(b) only 2 catch blocks

(c) multiple catch blocks

(d) none of the above

2.   _______________ class works as base class for an entire family of classes, declared in java.lang, that the program can initiate and throw.

(a) Exception

(b) RuntimeException

(c) InterruptedException

(d) Throwable

3.   For throwing the more serious problems, such as Out of Memory Error , may not be so easy to handle. Which of the following will be thrown?

(a) Exception

(b) ArithmethicException

(c) Error

(d) None of the above

4.   Exceptions are

(a) logical error

(b) compile time errors

(c) run time error

(d) none of the above

5.   String getMessage() is used to

(a) display the stack trace

(b) returns the description of the exception object thrown

(c) both (a) and (b)

(d) none of the above

6.   The correct statement for stack trace is

(a) A class in java.lang package

(b) An object of Exception class

(c) A useful debugging tool

(d) None of the above

7.   NumberFormatException class shows

(a) invalid conversion of a string to a numeric format

(b) invalid conversion of a numeric format to a string

(c) invalid conversion of a character to a numeric format

(d) invalid conversion of a numeric format to a character

8.   IllegalAccessException comes under the category of:

(a) unchecked Exceptions

(b) checked Exceptions

(c) (a) and (b)

(d) none of the above

9.   String toString() method is used to convert

(a) an integer data to string

(b) a class object into String object

(c) String object in a class object

(d) None of the above

10. The code give below:

import java.lang.*;
class test
{
   public static void main(String[] args)
   {
       try
       {
            int[] num = { 0, 1, 2, 3, 4 };
            int x = 25 / num[5];
            System.out.println("Control cannot reach here");
       }
       catch (ArrayIndexOutOfBoundsException E)
       {
            System.out.println("Exception thrown:");
            E.printStackTrace();
       }
   }
}

(a) Throws an exception at test.main(excep3.java:10)

(b) Throws an exception at test.main(excep2.java:9)

(c) Throws an exception at test.main(excep1.java:8)

(d) Throws an exception at test.main(excep4.java:10)

KEY FOR MULTIPLE CHOICE QUESTIONS

1.   c

2.   d

3.   c

4.   c

5.   b

6.   c

7.   a

8.   b

9.   b

10. b

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.190.211