Lab 13: Assertions and exceptions

Today, you'll be working with assertions and (again) with exceptions, this time with particular attention to defining and throwing them.

Clone the repository for this week's lab:

hg clone /cslab/class/csci235/lab13

I. Using assertions

We have frequently documented pre- and post-conditions for methods, and we have noted that if the caller does not satisfy the preconditions of a method, the behavior of the method is not defined. When a program does not work correctly, it would often be helpful to determine whether the fault lies in a class/method or in its caller. To assist in that, Java provides the assert statement, which consists of the reserved word assert followed by a boolean expression.

Normally, an assertion is treated like a comment, except for the fact that the expression must be able to be compiled. When you read a program with assertions, you known that a particular condition must be true at that point in the code. However, you can turn on checking of assertions when you run a program by giving the -enableassertions option on the Java command line. Java will then evaluate the boolean expression every time an assert statement is reached, and it will throw an AssertionError if the expression is not true. (Assertions are described briefly on pages 153-154 of the textbook.)

It can be especially helpful to write assertions for each method's preconditions. It is sometimes helpful to also assert postconditions, and, when the code is tricky, it may be helpful to assert things like loop invariants. In the first part of this lab, you will practice writing preconditions and assertions for them.

Change into the assert subdirectory for this lab. What you'll find there is a collection of classes that implement a slightly smarter array, supporting insertion, removal, and subarray, with a driver program for testing them.

What is missing in this case is the documentation of the preconditions for each of the methods in SmartArray. For each method in SmartArray, you need to

  1. Document appropriate preconditions, as described in the class's coding guidelines.
  2. Add assert statements that check these preconditions.

To see your assertions in action, you need to run the java command with the flag -enableassertions, as in

  java -enableassertions ArrayOps

You can abbreviate -enableassertions to -ea.

II. Defining and throwing exceptions

Change into the excepts directory. You will find there almost the same program. The key difference is that the methods of the SmartArray class in this version do not have the preconditions; they are instead supposed to throw a SmartArrayException if they are called with bad arguments.

You have been provided with a generic SmartArrayException class. What you will need to do is:

  1. Add the appropriate throws clauses to the methods for SmartArray.
  2. Modify those methods to throw appropriate kinds of SmartArrayException. If you have time, make subclasses of SmartArrayException for more specific kinds of errors; at the very least, though, provide a useful message.
  3. Add better exception handling to ArrayOps so that it prints appropriate messages and continues execution.

III. Turn in

To script your the execution of your programs

  1. Change into the top directory for this lab and start your typescript.
  2. Change into the asserts subdirectory, compile both source files, and the run the program several times with assertions enabled to show that it works for good input and fails appropriately for bad input.
  3. Now change into the except directory (cd ../excepts), compile all of the Java files (javac *.java), and again run your program several times to trip over a variety of the exceptions you throw.

After you end the script, make sure that you are in the top directory, and then

/cslab/class/csci235/bin/handin lab13 .
(note the dot!) to hand it all in.


Cary Gray
Last modified: Tue Apr 3 07:39:02 CDT 2012