16 Mar 1996

Exceptions

Shit Happens

The Java Interpreter makes sure that a program or applet cannot improperly access storage or interfere with other programs. Every time an object is used, it checks that the access variable does not contain null. When an access value is assigned, it makes sure that the type of the object designed by the value matches the constraints of the access variable. Every array index operation is check to make sure the index value is not less than 0 or beyond the number of elements in the array.

A program can be written to avoid most of these errors. It could check the access variable for null before using it, and it could test the value of every proposed index value. This makes the program much larger and slower, and the Interpreter will go ahead and make all the checks anyway.

Alternately, the program can provide an error handling routine that will receive control from the Interpreter when one of these internal tests fails. Once this mechanism is in place, it can be used by the standard library classes to provide recovery from library detected errors, when a file name is not found or a session is lost due to a network error.

The try statement introduces a block of code where errors are possible and a common error response is indicated. It is followed by one or more catch statements, each declaring a particular type of error that might occur:

try {pay_with_Visa();}
catch
(Dont_Take_Plastic err) {pay_Cash();}
catch (Over_Credit_Limit err) {pay_with_Amex();}

In Java, any unusual condition that might be detected and would interrupt normal processing is associated with a named class that extends the Exception class. They are generically called exceptions. Exceptions become a method of communication between internal methods that detect the problem and upper level application code that handles it. Since a source file can only contain one public class, and since exception classes have to be public to be useful, exception classes are generally defined separately in individual files and are then used by other classes that need them.

When an internal method detects a problem it creates an object associated with some exception class. It initializes the object with detailed information about the problem. It then passes the object to the Java Interpreter using a throw statement.

The Interpreter now checks up through the stack of active methods that have called other methods down to the point of error. It is looking for the first method that is currently executing inside a try block that has a catch statement referencing this type of exception.

Each catch statement declares a reference variable associated with an exception class. The block following the catch statement will be activated if a reference to the current exception object (from the throw statement) can be assigned to that exception reference variable. This means that the exception object must be in the class named by the catch statement or in a subclass derived by extending the catch class.

When more than one catch statement follows a try, they are tested in the order that they are coded. The first one that matches the exception class is executed. Therefore, more specific exception classes (specific subclasses of a general class) should be presented first, and general classes last. In the extreme case, the last catch statement could reference the Exception class itself and trap all errors.

The interpreter itself allocates and throws exception objects of specific classes in the language class library. The OutOfMemoryError exception class is thrown when a new operation fails because the new object cannot be created from available memory. The NullPointerException class is thrown when a program tries to use an instance variable or method through a reference variable containing the null reference value. Library classes throw exceptions as well, like the StringIndexOutOfBoundsException from the lang package and FileNotFoundException from the IO package.

An exception object may have a detail message providing more information about the error. This message can be extracted from the object by calling the getMessage() method. A programmer can create new exception classes if it is desirable to override getMessage or to provide additional data and methods that can be called by the code that handles the exception.

Exception handling is a required part of I/O or network programming. Many methods in these packages throw exceptions for many common conditions:

try {in = new FileInputStream(args[0]);}
catch (IOException e)
{System.out.println("Input file not found");return;}

An object of the FileInputStream class represents an open disk dataset. When a new FileInputStream object is created, the constructor accepts the file name as a String argument and opens the file. If the file is not found, the constructor throws an exception of the FileNotFoundException class, which is a subclass of IOException.

Continue Back PCLT

Copyright 1996 PC Lube and Tune -- Java H. Gilbert