A.9. Debugging
Professional programmers use sophisticated development environments to debug their programs. While these are beyond the scope of this book, we will mention three useful techniques: compiler error messages, System.out.println() statements, and assertions.
Compiler Error Messages
The Java compiler tries to catch as many errors as possible when compiling our programs. It can be annoying to battle the compiler, but it is much better to find errors at this point than to find them when the program is running. We don't have room to discuss all of the different error messages that arise, but there are a few things to keep in mind:
- Sun's widely used Java compiler indicates the file and line number on which an error occurs. Find out how to go to a specific line in your text editor.
- The compiler may report several errors on a single compilation attempt. Always fix the first error first. If the first error is something like a missing close bracket, the compiler may become deeply confused when reading the rest of the program, reporting errors that aren't really there. Fixing the first error may resolve many of the later "errors."
- A successful compilation does not mean your program is correct! You must test your program to make sure it does what it is supposed to do in every situation.
System.out.println() statements
A common question in debugging is, "What's going on at this line?" We may wish to verify that the program reached a certain line or to examine the values of variables at that point. This is easily done by inserting a System.out.println() statement:
System.out.println("Got to point B. x = " + x);
These statements can often produce far too much output. If this becomes a problem, it may be better to print a message only when something unusual happens:
if (x < 0) { System.out.println("Hey, x is negative!"); }
Be sure to remove these debugging statements before turning in your program.
Assertions
Assertions are a debugging feature which first appeared in Java 1.4. They provide a way of formalizing assumptions that we make in our programs. For example, suppose we assume that some variable x is positive. We can add this statement to our program:
assert x >= 0 : "Hey, x is negative!";
This is just like the previous bit of code, except that:
- It is considerably shorter. The syntax is the keyword assert, a boolean statement expressing what is supposed to happen, a colon, and then a message to be printed if the assertion fails.
- If any assertion fails, the program crashes immediately, printing the message we supplied and indicating where it occurred. This saves us time in sifting through debugging messages.
- Assertions can be turned on and off at run time. A program is easier to debug with assertions turned on, but has less work to do (and therefore runs faster) with assertions turned off.
To enable assertions, we must pass the -ea command-line option to Java when we run the program.
java -ea OurProgram
It is common to enable assertions while developing a program, but to disable them once we are fairly confident that the assertions are never violated.
Exercises
A.22 |
Add an assertion to the Circle program (Figure A-17) so that the program crashes if the user enters a negative radius. |