Site icon ICT Gurukul, GOLN

Programming with Exceptions

Programming with Exceptions

Programming with Exceptions

Today we will see the Programming with Exceptions. This lesson is part of Chapter 8.3.5 of Introduction to Programming Using Java.

Programming with Exceptions

Exceptions can be used to help write robust programs. They provide an organized and structured approach to robustness programming. Without exceptions, a program can become cluttered with if statements that test for various possible error conditions. With exceptions, it becomes possible to write a clean implementation of an algorithm that will handle all the normal cases. The exceptional cases can be handled elsewhere, in a catch clause of a try statement.

When a program encounters an exceptional condition and has no way of handling it immediately, the program can throw an exception. In some cases, it makes sense to throw an exception belonging to one of Java’s predefined classes, such as IllegalArgumentException or IOException. However, if there is no standard class that adequately represents the exceptional condition, the programmer can define a new exception class.

The new class must extend the standard class Throwable or one of its subclasses. In general, if the programmer does not want to require mandatory exception handling, the new class will extend RuntimeException (or one of its subclasses). To create a new exception class that does require mandatory handling, the programmer can extend one of the other subclasses of Exception or can extend Exception itself.

Here, for example, is a class that extends Exception, and therefore requires mandatory exception handling when it is used:

The class contains only a constructor that makes it possible to create a ParseError object containing a given error message. (The statement “super(message)” calls a constructor in the superclass, Exception. See Subsection 5.6.3.) Of course the class inherits the getMessage() and printStackTrace() routines from its superclass. If e refers to an object of type ParseError, then the function call e.getMessage() will retrieve the error message that was specified in the constructor.

But the main point of the ParseError class is simply to exist. When an object of type ParseError is thrown, it indicates that a certain type of error has occurred. (Parsing, by the way, refers to figuring out the syntax of a string. A ParseError would indicate, presumably, that some string that is being processed by the program does not have the expected form.)

A throw statement can be used in a program to throw an error of type ParseError. The constructor for the ParseError object must specify an error message. For example:

If the throw statement does not occur in a try statement that catches the error, then the subroutine that contains the throw statement must declare that it can throw a ParseError by adding the clause “throws ParseError” to the subroutine heading. For example,

This would not be required if ParseError were defined as a subclass of RuntimeException instead of Exception, since in that case exception handling for ParseErrors would not be mandatory.

A routine that wants to handle ParseErrors can use a try statement with a catch clause that catches ParseErrors. For example:

Note that since ParseError is a subclass of Exception, a catch clause of the form “catch (Exception e)” would also catch ParseErrors, along with any other object of type Exception. Sometimes, it’s useful to store extra data in an exception object. For example,

Here, a ShipDestroyed object contains an error message and some information about a ship that was destroyed. This could be used, for example, in a statement:

Note that the condition represented by a ShipDestroyed object might not even be considered an error. It could be just an expected interruption to the normal flow of a game. Exceptions can sometimes be used to handle such interruptions neatly.

The ability to throw exceptions is particularly useful in writing general-purpose subroutines and classes that are meant to be used in more than one program. In this case, the person writing the subroutine or class often has no reasonable way of handling the error, since that person has no way of knowing exactly how the subroutine or class will be used.

In such circumstances, a novice programmer is often tempted to print an error message and forge ahead, but this is almost never satisfactory since it can lead to unpredictable results down the line. Printing an error message and terminating the program is almost as bad since it gives the program no chance to handle the error.

The program that calls the subroutine or uses the class needs to know that the error has occurred. In languages that do not support exceptions, the only alternative is to return some special value or to set the value of some variable to indicate that an error has occurred. For example, the admeasurement() function in Subsection 8.2.2 returns the value -1 if the user’s input is illegal.

However, this only does any good if the main program bothers to test the return value. It is very easy to be lazy about checking for special return values every time a subroutine is called. And in this case, using -1 as a signal that an error has occurred makes it impossible to allow negative measurements. Exceptions are a cleaner way for a subroutine to react when it encounters an error.

It is easy to modify the readMeasurement() subroutine to use exceptions instead of a special return value to signal an error. My modified subroutine throws a ParseError when the user’s input is illegal, where ParseError is the subclass of Exception that was defined above. (Arguably, it might be reasonable to avoid defining a new class by using the standard exception class IllegalArgumentException instead.) The changes from the original version are shown in italic:

In the main program, this subroutine is called in a try statement of the form

The complete program can be found in the file From the user’s point of view, this program has exactly the same behavior as the program LengthConverter2 from the previous section. Internally, however, the programs are significantly different, since LengthConverter3 uses exception-handling.





Exit mobile version