Exceptions                                                                   P.Komisar
                                                                                                   latest minor  revision: Aug 15 / 2001

Exception handling is a plan for changing the flow of control of a program when an unexpected
event or error occurs. Control is diverted to a part of the program which can communicate to
the user. Exceptions are thrown by unacceptable conditions, such as dividing an integer by zero
or trying to access an array element outside of it's defined bounds.

Like most everything in Java, exceptions are handled using an object-based model. Program
problems are encapsulated in class objects. When an exception occurs, an Exception object
is created, specifically, one of many specialized descendants of Throwable, signalling to the
program it has a problem to deal with.(Error class is a unique branch of  Throwable wrapping
problems the programmer doesn't normally have to deal with.)

The programmer can choose to deal with an exception using a 'try...catch' construct or it
can pass the exception on up, (the call stack) all the way to main( ). If main doesn't handle
the exception, the program will halt with an error report explaining what happened.

The figure below shows the inheritance relations between Throwable and it's descendants.
The tree describes two branches. There is the Error branch and the Exception branch. The
Exception branch is subclassed to form the various checked exceptions. The Exception class
is subclassed by the RuntimeException exception class which is the parent of the various
runtime exceptions. The hierarchy essentially describes three groups of exceptions. Errors,
runtime exceptions and checked exceptions. A more detailed diagram is provided below
the figure. Notice even the detailed diagram doesn't show all the exception classes used
in the JDK. There are also special Exception classes (i.e.SQLException) defined inside
packages devoted to particular topics. It makes sense to house these specialized
Exception class types with the packages that use them.
 
 

Figure 1 The Exception Hierarchy

                                                              Object
                                                                  |
                                                          Throwable
                                                        /                  \
                                              Exception        Error
                                                 /       \
           RuntimeException      The various checked exceptions
                              /
        The various runtime exceptions
 

Exception Hierarchy Tree

 Abreviated  from the JDK  documentation. The Throwable hierarchy is all in java.lang package

  Object
         |
 Throwable
         |
         |__Error 
         |__Exception 
             |
             |__ClassNotFoundException
                |__CloneNotSupportedException
                |__IllegalAccessException
                |__InstantiationException
                |__InterruptedException
                |__NoSuchFieldException
                |__NoSuchMethodException
                  |
                  |______RuntimeException
                                        |
                                        |__ArithmeticException
                                        |__ArrayStoreException
                                        |__ClassCastException
                                        |__IllegalArgumentException
                                        |                      |__IllegalThreadStateException
                                        |                      |__NumberFormatException
                                        |
                                        |__IllegalMonitorStateException
                                        |__IllegalStateException
                                        |__IndexOutOfBoundsException
                                        |                    |__ArrayIndexOutOfBoundsException
                                        |                    |__StringIndexOutOfBoundsException
                                        |
                                        |__NegativeArraySizeException
                                        |__NullPointerException
                                        |__SecurityException
                                        |__UnsupportedOperationException
.

Throwable is parent to Exception and Error. Exception class includes checked and runtime exceptions
 

Checked exceptions   // errors a programmer can expect to  happen in a correct program

Checked exceptions arise in a correct program from problems arising during a program's
use. A user might make a typing error and enter a number where a letter should be located.
A power failure might cause an interruption in a network socket connection causing an
IOException to be thrown. These are types of error a programmer can expect to occur and
needs to be ready to handle. If a situation arises that may cause a checked exception to be
raised but the programmer hasn't provided a some code to handle the exception the compiler
will report the problem to the programmer. For instance the compiler might report something
like " java.lang.SomeKindOfException must be caught or declared to be thrown."  The
following example won't compile. The compiler reports InterruptedException must be
caught.

Example 

class CheckEx{
     public static void main(String args[]){
         Thread.sleep(1000);
         }
     }          // doesn't compile. reports InterruptedException
 

Runtime exceptions

Runtime exceptions are thrown by what are commonly called program bugs. A typical
example of this is when a loop is used that incorrectly references an array element that
is beyond the range of elements that have been defined. An example of this would be
accessing the tenth array element in an array that only has nine elements. This will cause
an ArrayOutOfBounds exception to be thrown. In a correct program, runtime exceptions
should never occur so you are not required to handle them. It is assumed the programmer
will fix any problems that cause these runtime exceptions to occur. In the case of runtime
exceptions, they show up and reported when the program is run. Runtime exceptions are
often harder to repair as they can result from what is correct code from the compilers
point of view. The code is correct in the sense it logical leads to the result that causes the
runtime exception to be thrown. To show the array out of bound problem the following
sample compiles fine but  at runtime throws an ArrayOutOfBounds exception.
 

Example      class ArrayBug{
                         public static void main(String args[]){
                               float []  f={1.01f };
                               System.out.println( f[1] );
                               }
                         }    // compiles but fails to run. ArrayOutOfBounds exception is thrown

Errors

Errors describe environmental problems which may be rare or difficult to recover from such
as running out of computer memory. You are not expected to handle Error class objects.
Hopefully you will never see them.

Error Handling Strategies

There are three stategies one can follow when dealing with exceptions. The first is more a lack
of stategy, don't do anything at all. It is possible to take this approach and you get the expected
results. The second is to defer dealing with the exception to a higher scope. The final stategy is
to use 'try catch and finally blocks to handle the occurence of exceptions.

Do Nothing

The first case scenario in dealing with exceptions is to do absolutely nothing! The Java compiler
only allows you to get away with this with RunTime and Error exceptions. This is not a wise
approach but more a demonstration of the simplest scenario. The following example shows an
exception waiting to happen.

Example         class Trouble{
                              public static void main(String[] args) {
                                  int x =1 / 0;
                                 System.out.println("We will never see this line printed");
                              }
                       }     // this will compile but an exception will be thrown by the runtime environment
 

Observe the class provides no plan to deal with the inevitable exception it is set to create. In
this case the exception is thrown in the main( ) method. Since main is the program's point of
entry, it doesn't have far far to go before being registered as an exception with the user. The
exception object is created and passed to the runtime which prints an error report to console
stating an ArithmeticException has been thrown and exits the program. If you look at detailed
class exception hierarchy described earlier you you will find the RuntimeException subclass,
ArithmeticException, listed.
 

User Defined Exceptions and the throw Statement

Before we get to the second stategy we show how a programmer can take control
of when an exception is thrown using the keyword throw. As well, we need to
consider that Java is an object-oriented environment. Even exceptions are defined
as classes that are used as templates to create exception objects. This opens the
possibility for the java programmer to use inheritance to define custom exception
classes. Custom exception classes are created by extending Exception class. The
programmer can use the throw keyword in conjunction with the given exception
class constructor to generate objects of this class in response to certain circumstances.
Exceptions are thrown implicitly when something illegal has occured in a program.
In contrast, exceptions are thrown explicitly with the keyword throw.

In the following example, a custom exception class called PartyException is created
by extending Exception. This exception object is thrown, in the BirthdayCalendar
call if some birthday condition is met.

Example

class PartyException extends Exception{
    PartyException( ){
    System.out.println("Time for a party");
    }
   }
 // class PartyException extends Exception and prints to console its "Time for a party"

class BirthdayCalendar{
  public static void main(String[] args) throws PartyException {
          // to get pass the compiler we show main throwing the exception
          //   Assume we have a list we loop through, itemizing  friend and and family birthdays
          //   Also assume the current date (plus some advance time) is compared to the list
          //    of birthdates.  If one is found,  a boolean value, a_birthday, is set to true
             if (a_birthday)  throw  new PartyException( );
         }
      }

Notice that the throw keyword is used in conjunction with the PartyException class
constructor and the new operator. There is something else here to note. Notice we
appended to main the suffix, 'throws PartyException'. This was neccessary to get the
code to compile. This satisfies the rule that states a method that may cause an exception
to be thrown must be defined showing explicitely which exception it can throw. This
leads to the next part of the discussion.

(Notice we didn't have to add a throws clause to main when we were dealing with
the ArithmeticException. This is ArithmeticException is a runtime exception. As was
discussed earlier, the programmer is not mandated to catch runtime exceptions. Not
to say it would not have been a good idea! There is nothing to stop us from catching
runtime exceptions.
 

Two Approaches to Handling Exceptions

As mentioned earlier, there are two possible approaches when dealing with exceptions
in java. We can 'deal' with the exception or 'pass them on'. An analogy can be created
where a clerk is dealing with an irate customer at a department store. The clerk can
decide to pacify the client or can pass the problem to higher authority by calling the
manager.

In Java, to pass the problem on involves using a throws clause. The second approach,
dealing with the problem requires the use of a try{ }catch( ) finally{ } construct.
 

The throws Statement

While throw causes an exception to be thrown, the keyword throws is appended to
a method's signature to show the method is capable of throwing an exception. The
throws clause declares that the use of the given method may result in an exception (of
the type declared) being thrown. This exception, if it is not handled by appropriate code
locally, will be passed 'up' into the next highest scope containing this method call.

The following example shows how a throws clause is appended to a method signature.

public static void sleep(long millis) throws InterruptedException

// The sleep( ) method is a static Thread class method. It has a couple overloaded
// forms. The commonest form takes an int value representing milliseconds.

Any method that throws an exception (and does handle the exception itself ) must be itself
declare it throws that exception. In the following example, the rest method is defined calling
sleep within it. ( Notice it calls the static method sleep, off of the Thread class name. This is
good form as it signals the reader that sleep is a static method.)

          public void rest( ) throws InterruptedException{
               Thread.sleep(60000);
              // sleep might be interrupted and throw InteruptedException
                }

Because sleep can throw an InterruptedException, the compiler now requires the enclosing
method, rest( ), to declare it throws this exception. If rest( ) is now called in another method
that method too must be declared as throwing InterruptedException and so on all the way up
to main( ). There is an alternative. The new methods can be written to handle any exceptions
that occur.

// We see in the excercises main( ) declared as throwing an exception to allow the code to compile

Handling Exceptions

Handling the exception is done in try / catch / finally blocks.

They take the form

try { // block }   opt.[ catch ( Exception e ) ]   opt.[  finally { // block } ]

1) For each try there has to be at least one catch or finally statement.
2) There can at most only one finally statement. There can be any number of catch statements.
3) Exception subclasses must be caught before their more general parent classes.

The following example shows how the rest( ) method would be rewritten in order
to handle the exception thrown by sleep( ).

 public void rest( ){
           try{
                Thread.sleep(60000);
                }
              catch(InterruptedException ie){
                System.out.println("Interrupted Exception");
                }

Handling Multiple Exceptions

In the following code section of an imaginary method, a variety of things can happen which
effects the control path taken.

//  ...
// somewhere inside a method
//...

try{
     // exceptions waiting to happen
      }
catch( SubException es){
     // say or do something
    }
catch( AnotherException ea){
     // say or do something
    }
catch( ParentException ep){
     // say or do something
    }
finally{
     // code executed in any case
    }

//  ...
// the next line following the finally block of the method
//  ...

1) If no exception occurs, the code in the try block finishes execution, the finally block
    executes and execution resumes at the line following the finally block.

2) If a SubException is thrown, execution leaves the try block at the point the exception
    was raised and goes to the catch block associated with SubException. After this code is
    executed, the finally block is executed and execution proceeds at the line following the
    finally block.

3) If a ParentException is thrown, execution exits the try block and proceeds at the catch
    block associated with the ParentException. Once this block executes, the finally block
    executes and control proceeds at the line following the finally block.

4) If an unknown exception occurs, execution proceeds directly to the finally block. When
    the finally block is finished executing, control leaves the method entirely. This is an uncaught
    exeception which will next appear in the caller.


Snapshot of the Exception class

The Exception class has a couple constuctor forms and several useful methods which
can be used to augment the information that is returned when an exception occurs.
For an example look at the end of the assignment section.
 

 Constructors
public Exception( )   Constructs an Exception with no specified detail message.
public Exception(String s)   Constructs an Exception with the specified detail message.

 Methods inherited from Throwable                                                                                                      3 of 7 methods
 String 
 getMessage( ) 
 Returns the error message string of this throwable object.
 void 
 printStackTrace( ) 
 Prints this Throwable and its backtrace to the standard error stream.
// there are two more printStackTrace methods, one prints the stack 
// trace to a specified print steam and another prints to a PrintWriter
 String 
 toString( ) 
  Returns a short description of this throwable object.



Exception Assignment 

Use the examples in the note to answer the following questions.

Q1.Write a class with no error protection that throws a divide by zero exception.

Q2.Write an exception class called Flat and throw it from an if clause with a boolean value,
      NoAir. (Don't use try and catch in this question. This will require declaring main( ) as
      throwing the exception.)

Q3 In a try clause throw Exception. In the corresponding catch clause catch the Exception
      object.On catching it, print to screen "Exception caught", and from a finally block, print
      to screen the word continuing.

Q4 Using the info found at the top of page 193, 'Just Java', add a string, "probably a nail" to
      the Flat exception you wrote earlier via the constructor and using super( ) so that when
      the getMessage( ) method is called on a Flat object, this string is also printed to screen.



If you don't have this text a copy will be available. You can also figure this out using the API. For your
convenience, you can use the description ('snapshot') of the Exception class included at the end of the
Exception note.

When Flat extends the Exception class, give it a constructor  using the form below where it takes a string.
Then invoke the parent constructor, in the first line of code using super(s), where s is the String argument
identifier of the Flat constructor.

For example

class MotorFailure extends Exception{
   MotorFailure(String cause){
   super(cause);
   }
}        // should really add the no-args constructor as well now in case someone extends this class

Now this exception class can be instantiated with the constructor that takes a descriptive string. This
string is returned if getMessage( ) is called on the exception object thrown.

For example

class MotorTest{
public static void main(String[]args){
 try {
       throw new MotorFailure("blown gasket");
      }
      catch(MotorFailure mf){
           System.out.println( mf.getMessage( ));
          }
    }
}