Page: (Bot) (Prev) (Next) Class: (Outline) (Summary) (Assign) (Answer) Course: (Cover) (Content) (Glossary)
IT508 - INTERNET PROGRAMMING - CLASS 4
ERRORS AND EXCEPTIONS

To: (Exception) (Catch) (Custom)

EXCEPTIONS (Top)

The following diagram shows the basic exception hierarchy:

[EXCEPTION HIERARCHY]

The classes in the exception hierarchy are:

public class Object
The ancestor to all Java objects.

public class Throwable
An instance of the java.lang.Throwable class, or its descendents, can be thrown using a throw statement and subsequently caught using a catch statement. Although you can throw and catch instances of Throwable and create your own subclasses from Throwable, you should normally start with the Exception hierarchy.

public class Error extends Throwable
The java.lang.Error class is the superclass of classes that represent erroneous and abnormal events that are detected by the Java virtual machine. Error should not be subclassed by user programs. Instances of Error and its subclasses should not be thrown or caught by user programs. The throws clause of a method does not need to specify an Error, even if it is thrown by the method.

public class Exception extends Throwable
The java.lang.Exception class is the superclass of exceptional conditions. The RuntimeException hierarchy, represents runtime errors that are considered unrecoverable and should not be caught. All the other subclasses of Exception represent errors that are thought to be non-fatal so they should be caught and an attempt should be made to recover from their consequences. Among others, Java contains a number of Exception subclasses to identify potentially recoverable input/output errors. New types of exceptions should be subclasses of Exception.

public class RuntimeException extends Exception
Instances of the java.lang.RuntimeException and its subclasses are caught by the Java runtime and indicate unrecoverable conditions indicative of programming errors. This includes such things as array index out of bounds and arithmetic errors. A RuntimeException is treated much like an Error. RuntimeException should not be subclassed by user programs. Instances of RuntimeException and its subclasses should not be thrown and normally should not be caught by user programs. The throws clause of a method does not need to specify a RuntimeException, even if it is thrown by the method.

The NumberFormatException, a subclass of RuntimeException is thrown by methods that convert strings to numeric data types. If you are interacting with a user, it may be worthwhile to catch this exception.

Nothing prevents you from throwing a RuntimeException and since they do not need to be declared in the throws clause, some programmers will use this type of exception to avoid the work of handling exceptions properly. But, this is not good programming practice.
As indicated in the following diagram that shows part of the exception hierarchy, there are quite a few predefined exceptions:
  Object
    |
    +-- Throwable
          |
          |-- Error
          |     |
          |    ...
          |
          +-- Exception
                |
                |-- java.awt.AWTException
                |
                |-- ClassNotFoundException
                |
                |-- CloneNotSupportedException
                |
                |-- IllegalAccessException
                |
                |-- InstantiationException
                |
                |-- InterruptedException
                |
                |-- java.io.IOException
                |     |
                |     |-- EOFException
                |     |
                |     |-- FileNotFoundException
                |     |
                |     |-- InterruptedIOException
                |     |
                |     |-- UTFDataFormatException
                |     |
                |     |-- java.net.MalformedURLException
                |     |
                |     |-- java.net.ProtocolException
                |     |
                |     |-- java.net.SocketException
                |     |
                |     |-- java.net.UnknownHostException
                |     |
                |     +-- java.net.UnknownServiceException
                |
                +-- RuntimeException
                      |
                      |-- Arithmetic Exception
                      |
                      |-- ArrayStoreException
                      |
                      |-- ClassCastException
                      |
                      |-- IllegalArgumentException
                      |     |
                      |     |-- IllegalThreadStateException
                      |     |
                      |     +-- NumberFormatException
                      |
                      |-- IndexOutOfBoundsException
                      |     |
                      |     |-- ArrayIndexOutOfBoundsException
                      |     |
                      |     +-- StringIndexOutOfBoundsException
                      | ...

CATCHING EXCEPTIONS (Top)

Exceptions are passed up through the stack of invoking methods until they are caught. The catcher of last resort is the Java virtual runtime that will display the exception and dump a stack trace for any exception that is not caught.

The following illustrates a version of the standard main method that is sometimes useful when you want to test a program that can generate various types of errors:

  public class TestProg
  {
  
      private static void execute() throws ....
      {
      // --- Insert test code here
      }
  
      public static void main(String[] args)
      {
      //Display init message
          System.out.println("-- INIT TEST NAME");
      //Run until user says stop
          boolean run = true;
          while (run)
            {
         ///Try to execute
  /*1*/       try
                {
                  execute();
                } //try
          //Catch all exceptions
  /*2*/       catch (Exception error)
                {
              //Rethrow runtime exceptions
  /*3*/           if (error instanceof RuntimeException)
                    throw (RuntimeException)error;
              //Display other exceptions
  /*4*/           System.out.println("** EXCEPTION DETECTED");
                  System.out.println("   " + error.getMessage());
                  error.printStackTrace(System.out);
                } //catch
          //Ask if want to run again
              try
                {
  /*5*/            System.out.println();
                   System.out.print("Type y to execute again: ");
                   System.out.flush();
                   int c = System.in.read();
                   run = (c == 'y') || (c == 'Y');
  /*6*/            while (System.in.read() != 'n');
                   System.out.println();
                }
              catch (IOException error)
                {
                   System.out.println();
                   System.out.println("** IO EXCEPTION GETTING YOUR ANSWER");
                   System.out.println("  " + error.getMessage());
                   run = false;
                }
            } //while
      //Display term message
          System.out.println("-- TERM TEST NAME");
      }
  
  }
------------
  1. Try to execute the test.
  2. Catch all Exception and its subclasses that were thrown and not already caught. Unfortunately, this also catches RuntimeException.
  3. If the Exception is really an instance of one of the RuntimeException classes, throw it again so the runtime can handle it.
  4. Handle the exception. Here we just print the message and also dump the stack so that we can see where the exception originated.
  5. Ask the user if the test should be executed again. But, this could generate its own IOException.
  6. Since console input is buffered until the enter is typed, the enter (newline) must be skipped.

The source code for this main method is included in a simple exception test program. You may want to play with your own copy.

CUSTOM EXCEPTIONS (Top)

A programmer may choose to create new Exception subclasses for several reasons.

  1. Since the following exception subclass relies on its parent to perform all of its operations, its only purpose is to provide a descriptive name for a new type of exception.
      public class MyDescriptiveException extends Exception
      {
          public MyDescriptiveException()
          {
              super();
          }
    

    public MyDescriptiveException(String message) { super(message); } }

  2. This next exception subclass also provides a descriptive name. But since it does not provide a default constructor, the programmer is forced to supply a message that describes the reason for the exception.
      public class MyRestrictiveException extends Exception
      {
          public MyRestrictiveException(String message)
          {
              super(message);
          }
      }
    

  3. An Exception subclass can add additional state and additional methods. One reason for this might be to record the object instance that threw the exception so that the catcher can access the guilty object. For example this exception requires a source instance and a message. It also adds a method to allow the catcher to get a reference to the source instance.
      public class MyObjectException extends Exception
      {
          private MyObject theSource;
    

    public MyObjectException(MyObject source, String message) { super(message); theSource = source; }

    public MyObject getSource() { return(theSource); } }

    Now, this exception can be thrown by anyone, including an instance of MyObject as the following illustrates.
      public class MyObject
      {
      //Size limit constants
          private static final int minSize = 1;
          private static final int maxSize = 100;
    

    //Instance variables private int theSize;

    public MyObject(int size) throws MyObjectException { //Save size theSize = size; //Validate size if (size < minSize) throw new MyObjectException(this,"Size below minimum"); if (size > maxSize) throw new MyObjectException(this,"Size above maximum"); }

    public int getSize() { return(theSize); }

    ..... }

    Notice that the object instance that is passed to the new exception is this object.


Page: (Top) (Prev) (Next) Class: (Outline) (Summary) (Assign) (Answer) Course: (Cover) (Content) (Glossary)

Prepared by David L. March -- Last Revised on September 22, 1998
COPYRIGHT © 1998 BY DAVID L. MARCH