Chapter 11

Test Your Thinking

A well-written program is one-third "program" and two-thirds error checking. Far too many programs are written with the assumption that everything is going to work fine. You've probably heard of Murphy's Law: Whatever can go wrong, will go wrong. There are also those who say that Murphy was an optimist. Those people are right. Just as a person's true character is revealed under duress, the same is true for a computer program. Your well-written programs should always consider what should be done if the unexpected, or even impossible, should occur.

1) Create a new exception called NoMoreElementsException, which is a subclass of Exception.

Answer:

If you were able create your own subclass of Exception in Lab 11.4, you should not have encountered any difficulties while creating the NoMoreElementsException exception.

Similar to the solution to Lab exercise 11.4.1, Create Your Own Exceptions, a simple subclass of Exception will do nicely. Since our exception does not require any extended functionality, all that is needed is a default (empty) constructor and an alternate constructor that takes a String as a message. As you may recall from the chapter, the second constructor is not mandatory, but is considered good form for exception classes.

If you are asking “Why the heck am I creating a subclass of Exception if I do not require any extended functionality,” take a deep breath and repeat after me, “I may not need extended functionality from this class now, but I very well might in the future.” As well, remember that creating a new exception allows you to catch your specific exception instead of a more ambiguous exception class.

For our answer, we created one new class: the NoMoreElementsException class. You should have created only one new class as well, and it should have been named identically.

Click here for the NoMoreElementsException.java source code.

2) Modify the Stack and Queue classes created in Chapter 10 (Test Your Thinking) so that the pop() and remove() methods will throw a NoMoreElementsException if you try to pop an empty stack, or remove an item from an empty queue.

Answer:

Completion of this question can be broken-down into three distinct steps: modify the method declarations so that they advertise the exception, create code within the methods to throw the exception when appropriate, and modify any existing code that calls these methods.

As discussed within the chapter, a method must advertise the exceptions that it is able to throw—this allows the Java compiler to enforce that all callers of the method are able to catch the possible exceptions. Using our stack and queue classes from the previous chapter, following are the modified method declarations with new code in boldface type:

/**

* Remove and element from the beginning of the queue.

*

* @return the first element in the list

* @throws NoMoreElementsException if removal

* is attempted from empty queue

*/

public Object remove()

throws NoMoreElementsException

{

// Make sure we have elements to return.

if (list.size() == 0)

throw(new NoMoreElementsException(

"Queue is empty"));

return list.remove(0);

}

As you can see, we simply advertised the NoMoreElementsException, and replaced the previous return call with code to throw a new exception. For good measure, we also updated the documentation for the method—while not required, this is good programming practice.

The stack object’s pop method was updated as follows:

/**

* Remove and element from the beginning of the list.

*

* @return the first element in the list.

* @throws NoMoreElementsException if pop is

* attempted from an empty stack

*/

public Object pop()

throws NoMoreElementsException

{

// Make sure we have elements to return.

if (list.size() == 0)

throw(new NoMoreElementsException(

"Stack is empty"));

return list.remove(0);

}

As with the previous method, we simply advertise the exception, and insert code to throw the exception when necessary. The documentation was updated as well, because programmers are a fickle lot, and would not allow such an omission to go unnoticed.

Are we done yet? Hardly. We have covered two of the three bases, but now we must make sure that all callers of these methods are able to catch the exception that may now be thrown. There are two approaches to this—do a text search on all your Java classes to find calls to these two methods, or the lazy-man’s method of allowing the compiler to do the work. Classes that fail to call the above methods within a try/catch block will fail to compile. We won’t attempt to influence your decision on this, though we are firm believers that laziness can be a virtue for programmers.

From the Test Your Thinking section of the previous chapter, a TestStack class was presented. We have modified that class to correctly call these methods. You may or may not have created a class to test your MyStack and MyQueue classes; if you did, be sure to update your test class as well. If you didn’t, shame on you—how can you be sure your classes work without a program to perform unit-testing?

Click here for the MyStack.java source code.

Click here for the MyQueue.java source code.

Click here for the TestStack.java source code.

Click here to run the TestStack applet.