13. Exceptions: When Things Go Wrong

13.6. Creating and Throwing Your Own Exceptions

 

Like other Java classes, the Exception class can be extended to handle cases that are not already covered by Java’s built-in exceptions. Exceptions that you define will be handled the same way by the Java interpreter, but you will have to throw them yourself.

For example, Figure 10.20 shows the design of an exception that can

be used for validating that an integer is less than or equal to a certain maximum value. It would be coded as follows:

,,

 

 

 

 

 

 

 

 

 

The class extends Exception and consists entirely of a constructor method that calls the superclass constructor. The argument passed to the superclass constructor is the message that will be returned by getMessage() when an instance of this exception is created.

Now let’s consider an example where this new exception will be

thrown. Suppose we wish to constrain the IntField class that we de- veloped previously (Fig. 10.14) so that it will only accept numbers that are less than a certain bound. First, let’s modify IntField so that its bound can be set when an instance is created. We want its bound to be an instance variable with some initial value, and we want to provide a constructor that can be used to override the default (Fig. 10.21).

This leads to the following revision of IntField:

,


J

 

 

 

 

 

IntField

-bound : int

+IntField()

+IntField(in size : int)

+IntField(in size : int, in max : int)

+getInt() : int

,

Figure 10.21: The revised IntField class contains a bound on the size of the numbers that should be entered.

 

 

 

 

 

J

Our new constructor has the signature IntField(int,int), which doesn’t duplicate any of JTextField’s constructors. This is good design, because in extending a class, we want to be careful about the effect that our definitions have on the original methods in the superclass. Superclass methods should be overridden by design, not by accident. If a method is

 

,,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

J

Figure 10.22:The revised IntField class containing the revised

getInt() method.

 

redefined inadvertently, it might not function as expected by users of the subclass.

Note how we have handled the problem of setting the default value of the bound. Integer.MAX VALUE is a class constant that sets the maximum value for the int type. It’s an appropriate value to use, be- cause any valid int that the user types should be less than or equal to MAX VALUE. Given these changes to IntField, let’s now incorporate our new exception into its getInt() method (Fig. 10.22).

This new version of getInt() throws an exception if the integer en- tered by the user is greater than the IntField’s bound. Here again, it is difficult to handle this exception appropriately in this method. The method would either have to return an erroneous value—because it must return something—or it must terminate. Neither is an acceptable alterna- tive. It is far better to throw the exception to the calling method.

The IntFieldTester class (Fig. 10.23) has the design and function- ality shown in Figure 10.15. It provides a simple GUI interface to test the IntField class. It prompts the user to type an integer that is less than 100, and then it echoes the user’s input. Note how the exception is

 

handled in the actionPerformed() method. If an exception is thrown in IntField.getInt(), the actionPerformed() method pops up an error dialog, and the erroneous input is not used. Instead, the user is given another chance to enter a valid integer.

 

SELF-STUDY EXERCISES

EXERCISE 10.14 Define a new Exception named FieldIsEmpty- Exception, which is meant to be thrown if the user forgets to enter a value into a IntField.

EXERCISE 10.15 Modify the IntField.getInt() method so that it throws and catches the FieldIsEmptyException.

 

 

From the Java Library: JOptionPane

A dialog box is a window that can be opened by a program to communi- cate in some way with the user. Dialog boxes come in many varieties and have many uses in a GUI environment. You’ve undoubtedly encountered them when using your own computer.

For example, a file dialog is opened whenever you want to open or save a file. It provides an interface that lets you name the file and helps you search through the computer’s directory structure to find a file.

A warning dialog or error dialog is opened whenever a program needs to notify or warn you that some kind of error occurred. It usually presents an error message and an OK button that you click to dismiss the dialog.

Dialogs are easy to create and use in Java. The Swing component set provides several different kinds of basic dialogs that can be incorpo- rated into your program with one or two lines of code. For example, the IntFieldTester class makes use of a simple message dialog to report an input error to the user. This dialog was created by the following code segment in the program (see Figure 10.23):

,,


 

 

 

 

 

 

 

 

java.sun.com/j2se/1.5.0/docs/api/

 

 

 

 

 

J

This method call displays the window shown in Figure 10.16. It con- tains the error message and an OK button that is used to close the win- dow. The showMessageDialog() method is a static method of the javax.swing.JOptionPane class. This class provides a collection of similar methods for creating and displaying basic dialog boxes.


 

Creates

 

A dialog differs from other kinds of top-level windows—such

as JApplet and JFrame—in that it is associated with another

 

window (Fig. 10–24). The first parameter in this version of the showMessageDialog() method is a reference to the dialog’s parent window. The second parameter is a String representing the message.

The basic message dialog used in this example is known as a modal dialog. This means that once it’s been displayed, you can’t do anything else until you click the OK button and dismiss the dialog. It’s also possible


Figure 10.24: A dialog window cannot stand alone. It must be cre- ated by a top-level window.

 

,,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

J

Figure 10.23: An application that uses an IntField object to process integers.

 

to create nonmodal dialogs. These can stay around on the screen while you

move on to other tasks.Modal and nonmodal dialogs

Note that the dialog box also contains an icon that symbolizes the pur- pose of the message (Fig. 10.25). The icon is representative of the dialog’s

 

 

 

message type. Among the basic types available in JOptionPane are the following:

,,


Figure 10.25: An error dialog.

 

 

 

 

 

J

To set the dialog to anything other than the default (informational) type, you can use the following version of showMessageDialog():

,,

 

J

The first parameter is a reference to the parent window. The second is the message string. The third is a string used as the dialog window’s title, and the fourth is one of the five dialog types. For example, we can change our dialog to an error dialog with the following statement:

,,

 

 

 

 

 

 

This would produce the dialog shown in Figure 10.25.

The other kinds of basic dialogs provided by the JOptionPane class are listed in Table 10.4. All of the dialogs listed there can be created with a line or two of code. In addition to these, it’s also possible to create sophis- ticated dialogs that can be as customized as any other GUI interface you can build in Java.


J

 

 

Basic Swing dialogs

 

TABLE 10.4 Basic dialogs provided by JOptionPane.

DialogDescription

Message DialogPresents a simple error or informational message Confirm DialogPrompts the user to confirm a particular action Option DialogLets the user choose from some options

Input DialogPrompts and inputs a string

 

In this chapter, you have learned how to handle exceptional conditions that occur in programs. You now know that Java has a default excep- tion handler that can take of many situations, and you also understand that proper program design using Java excpetion-handling elements helps deal with many other situations. This chapter continues the emphasis on good program design for creating useful, stable programs.

 

 

 

CHAPTER SUMMARYTechnical Terms

catch block

catch an exception checked exception dialog box dynamic scope error dialog


 

exception exception handling finally block method call stack method stack trace modal dialog


 

static scope

throw an exception try block

unchecked exception

 

The Try/Catch Statement

The try/catch/finally statement has the following syntax:

,,

 

 

 

 

 

 

 

 

 

 

 

 

 

J

The try block is meant to include a statement or statements that might throw an exception. The catch blocks—there can be one or more—are meant to handle exceptions that are thrown in the try block. A catch block

 

CHAPTER 10 Chapter Summary493

will handle any exception that matches its parameter class, including sub- classes of that class. The finally block is optional. It will be executed whether an exception is thrown or not. If an exception is thrown in the try block, the try block is exited permanently.

The throw statement inside the try block is there to illustrate how throw can be used. You will usually not see a throw statement in a try block, because most throws are done from within Java library methods, which are called from a try block.

 

Summary of Important Points

In Java, when an error or exceptional condition occurs, you throw an Exception, which is caught by special code known as an exception handler. A throw statement—throw new Exception()—is used to throw an exception.

A try block is a block of statements containing one or more statements that may throw an exception. Embedding a statement in a try block indicates your awareness that it might throw an exception and your intention to handle the exception.

Java distinguishes between checked and unchecked exceptions. Checked exceptions must either be caught by the method in which they occur or you must declare that the method containing that statement throws the exception.

Unchecked exceptions are those that belong to subclasses of Runtime- Exception. If they are left uncaught, they will be handled by Java’s default exception handlers.

A catch block is a block of statements that handles the exceptions that match its parameter. A catch block can only follow a try block, and there may be more than one catch block for each try block.

The try/catch syntax allows you to separate the normal parts of an algorithm from special code meant to handle errors and exceptional conditions.

A method stack trace is a trace of the method calls that have led to the execution of a particular statement in the program. The Exception.printStackTrace() method can be called by excep- tion handlers to print a trace of exactly how the program reached the statement that threw the exception.

Static scoping refers to how the text of the program is arranged. If a vari- able is declared within a method or a block, its static scope is confined to that method or block.

Dynamic scoping refers to how the program is executed. A statement is within the dynamic scope of a method or block if it is called from that method or block, or if it is called by some other method that was called from that method or block.

When searching for a catch block to handle an exception thrown by a statement, Java searches upward through the statement’s static scope and backward through its dynamic scope until it finds a matching catch block. If none is found, the Java Virtual Machine will handle the exception itself by printing an error message and a method stack trace. Many Java library methods throw exceptions when an error occurs. These throw statements do not appear in the program. For example,

 

Java’s integer division operator will throw an ArithmeticException if an attempt is made to divide by zero.

Generally, there are four ways to handle an exception: (1) Let Java han- dle it; (2) fix the problem that led to the exception and resume the pro- gram; (3) report the problem and resume the program; and (4) print an error message and terminate the program. Most erroneous conditions reported by exceptions are difficult or impossible to fix.

A finally statement is an optional part of a try/catch block. State- ments contained in a finally block will be executed whether an excep- tion is raised or not.

A well-designed program should use exception handling to deal with truly exceptional conditions, not as a means of normal program control. User-defined exceptions can be defined by extending the Exception class or one of its subclasses.

 

 

 

SOLUTIONS TO

SELF-STUDY EXERCISES


SOLUTION 10.1

Integer.parseInt("26.2"); ==> NumberFormatException

String s; s.indexOf(’a’); ==> NullPointerException

 

String s = "hello"; s.charAt(5); ==> StringIndexOutOfBoundsExcepti

SOLUTION 10.2 The unchecked exceptions are IndexOutOfBoundsException, NumberFormatException, and NullPointerException, because these are subclasses of RuntimeException. The others are checked exceptions.

SOLUTION 10.3 An ArrayIndexOutOfBoundsException could be handled by the handlers in a, c, or d, because their classes are all superclasses of Array- IndexOutOfBoundsException.

SOLUTION 10.4 If Math.random() in MyClass2 returns 0.98 and then 0.44, the program will generate the following output:

,,

 

J

Note that because the out-of-range error occurs in method1(), method2() is not called at all.

SOLUTION 10.5 If Math.random() in MyClass2 returns 0.98 and then 0.44, the following stack trace would be printed:

,,

 

 

J

SOLUTION 10.6 If Math.random() in MyClass2 returns 0.44 and then 0.98, the program will generate the following output:

,,

 

J

 

CHAPTER 10 Solutions to Self-Study Exercises495

SOLUTION 10.7 If Math.random() in MyClass2 returns 0.44 and then 0.98, the following stack trace would be printed:

,,

 

 

J

SOLUTION 10.8 The divide-by-zero error in BadDivide occurs in the expres- sion n/d in Method2(). It would generate the following stack trace:

,,

 

 

 

J

SOLUTION 10.9 The following version of BadDivide.method2() will handle the divide-by-zero error itself:

,,

 

 

 

 

 

 

J

SOLUTION 10.10 If someValue equals 1000, the code segment will print

,,

 

J

SOLUTION 10.11 If someValue equals 50, the code segment will print

,,

 

J

SOLUTION 10.12

,,

 

 

 

 

 

J

SOLUTION 10.13

 

It depends. This is a computer game, so one way to handle this problem would be to generate a message into a log file and resume the game. If the GUI element is crucial to the game, it’s hard to see how it could be successfully handled.

It depends. You would have to decide whether it would be more harmful or dangerous to continue production than not.

The program could report the security violation to the user and to the system manager and then keep accepting user input.

SOLUTION 10.14

,,

 

 

 

J

SOLUTION 10.15

,,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

J

 

 

 

EXERCISES

Note: For programming exercises, first draw a UML class diagram describing all classes and their inheritance relationships and/or associations.


EXERCISE 10.1 Explain the difference between the following pairs of terms:

Throwing an exception and catching an exception.

Try block and catch block.

Catch block and finally block.

Try block and finally block.

Dynamic scope and static scope.

Dialog box and top-level window.

Checked and unchecked exception.

Method stack and method call. EXERCISE 10.2 Fill in the blanks.

 

CHAPTER 10 Exercises497

an exception is Java’s way of signaling that some kind of abnormal situation has occurred.

The only place that an exception can be thrown in a Java program is within a

.

The block of statements placed within a catch block is generally known as an

.

To determine a statement’sscope, you have to trace the program’s execution.

To determine a statement’sscope, you can just read its definition.

When a method is called, a representation of the method call is placed on the

.

The root of Java’s exception hierarchy is theclass.

Aexception must be either caught or declared within the method in which it might be thrown.

Anexception can be left up to Java to handle.

EXERCISE 10.3 Compare and contrast the four different ways of handling ex- ceptions within a program.

EXERCISE 10.4 Suppose you have a program that asks the user to input a string of no more than five letters. Describe the steps you’d need to take in order to design a StringTooLongException to handle cases where the user types in too many characters.

EXERCISE 10.5 Exceptions require more computational overhead than normal processing. Explain.

EXERCISE 10.6 Suppose the following ExerciseExample program is cur- rently executing the if statement in method2():

,,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

J

Draw a picture of the method call stack that represents this situation.

 

EXERCISE 10.7 Repeat the previous exercise for the situation where the pro- gram is currently executing the second println() statement in method1().

EXERCISE 10.8 Draw a hierarchy chart that represents the static scoping rela- tionships among the elements of the ExerciseExample program.

EXERCISE 10.9 What would be printed by the ExerciseExample program when it is run?

EXERCISE 10.10 What would be printed by the ExerciseExample program, if the statement in its main method were changed to ex.method1(5)?

EXERCISE 10.11 Consider again the ExerciseExample program. If the ex- ception thrown were Exception rather than ArithmeticException, explain why we would get the following error message: java.lang.Exception must be caught, or it must be declared....

EXERCISE 10.12 Write a try/catch block that throws an Exception if the value of variable X is less than zero. The exception should be an instance of Exception and, when it is caught, the message returned by getMessage() should be “ERROR: Negative value in X coordinate.”

EXERCISE 10.13 Look at the IntFieldTester program (Fig. 10.23) and the IntField class definition (Fig. 10.22). Suppose the user inputs a value that’s greater than 100. Show what the method call stack would look like when the IntField.getInt() method is executing the num > bound expression.

EXERCISE 10.14 As a continuation of the previous exercise, show what the program’s output would be if the user input a value greater than 100.

EXERCISE 10.15 As a continuation of the previous exercise, modify the IntOutOfRangeException handler so that it prints the message call stack. Then show what it would print.

EXERCISE 10.16 Define a subclass of RuntimeException named Invalid- PasswordException, which contains two constructors. The first constructor takes no parameters and an exception thrown with this constructor should re- turn “ERROR: invalid password” when its getMessage() is invoked. The sec- ond constructor takes a single String parameter. Exceptions thrown with this constructor should return the constructor’s argument when getMessage() is invoked.

EXERCISE 10.17 Extend the IntField class so that it will constrain the integer JTextField to an int between both a lower and upper bound. In other words, it should throw an exception if the user types in a value lower than the lower bound or greater than the upper bound.

EXERCISE 10.18 Design Issue: One of the preconditions for the Insertion- Sort() method (Fig. 9.13) is that its array parameter not be null. Of course, this precondition would fail if the array were passed a null array reference. In that case, Java would throw a NullPointerException and terminate the program. Is this an appropriate way to handle that exception?

EXERCISE 10.19 With respect to the previous exercise, suppose you decide that it is more appropriate to handle the NullPointerException by presenting an error dialog. Modify the method to accommodate this behavior.

EXERCISE 10.20 Design Issue: Another possible way to design the sequential- Search() method (Fig. 9.16) would be to have it throw an exception when its key is not found in the array. Is this a good design? Explain.

 

 

 

 

 

 

 

 

 

Chapter 11