|
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
We will finish lab08a—printing: Pair O' Dice (checking off step 10).
If you finish that, you can read on for fun…
We mentioned last time, that one use of System.out.println is to help debug: You might stick in statements which print out the current value of a variable, or which just let you know that a certain method is even being called (perhaps indirectly). For instance, you might put a System.out.println inside a setter method, to see if a variable is ever being changed.
The problem with this approach is that you later need to comment out all those printlns. And then a while later, you might want to put them back in.
Instead of calling System.out.println directly, make a MyDebug class:
class MyDebug { boolean on = false; // Is debug-printing turned on? /** Turn debug-printing on or off. * @param turnOn Turn printing on? */ void setPrinting( boolean turnOn ) { this.on = turnOn; } /** Print a message (if debugging is currently turned on). * @param msg The debug message to print. */ public void dprint( String msg ) { if (this.getOn()) { System.out.println( msg ); } } /* Getter for `on`. */ private boolean getOn() { return this.on; } } |
By making several MyDebug objects, you can even have separate debugging for different parts of your code. (Although you now don't have a single master switch for all debugging.) In practice, one MyDebug object per class is usually about right.
Your task (optional):
Add this class MyDebug to your lab.
In PairODice, add such an object as another field.
Add calls to dprint, and run your test cases.
Then, turn printing off and run it again.
(Some people like providing a myDebug
constructor which takes in the initial
on/off status, as well.)
Possible extensions: you can generalize on to an int debugPriority; every call to dprint might include a priority-level of that information, and if that statement's priority level doesn't exceed the current debugPriority then it gets printed:
d.dprint(3, "Btw, the current value of x is " + x ); //or: d.dprint(1, "Uh-oh, we unexpectedly reached the end of an if-else; Panic!" ); |
Drawbacks: This doesn't work across classes. Also, making the MyDebug object a field of your class is
See also: assert.
Note that BlueJ's built-in debugger is also helpful: if you click on the line-number in a BlueJ file, it will put a little stop-sign (a “breakpoint”) by that line. Then you can run your program/tests as normal, but when BlueJ reaches a breakpoint, it pauses executing and puts up a debugger-window. The debugger-window: (a) shows you all the local variables and fields of the current method/object, and (b) lets you follow the next lines step-by-step.
Writing small methods and making test cases is the best way to avoid bugs. Using a debugger is also very good, but the println-debugging is also an option for figuring out where your program is going awry.
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
©2007, Ian Barland, Radford University Last modified 2007.Oct.10 (Wed) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |