Consider letting the less experienced member of the group do the typing if it seems like there's a mismatch in experience or comfort levels. That will help make sure they don't get left behind. Worst case, flip a coin to see who does the typing. Or have Java generate a random boolean value. (Type (new java.util.Random()).nextBoolean()
in the codepad.)
At the conclusion of the lab, make arrangements for the typer to share a copy of the code with the other member(s) of the group. (E.g. email it, or put it on a shared Google drive, etc.) My solutions to the lab will get posted as well.
DieRoller
class, and a Tester
class that creates a HistoryDie instance and passes it to some DieRoller methods. Run its main method to see what it does.
HistoryDie
constructor: Comment out the line that allocates the array holding the counts, so that the array reference will be null. After compiling, create an instance in the codepad (or by right-clicking on HistoryDie
and creating a new one) and call its roll()
method. Note that the constructor runs without an error, but we get into trouble once we roll the die instance:
> HistoryDie d = new HistoryDie(6); > d.roll() Exception: java.lang.NullPointerException (null)
BlueJ reports the error in the codepad, but it also gives a more complete summary of the error in the terminal window that includes details about where in the program the error occurred:
java.lang.NullPointerException at HistoryDie.roll(HistoryDie.java:32)
Tester
class's main method and look closely at the error report in the terminal window. What do the additional lines mean? What are they telling you?
Tester
's main method: put the call to rollRepeatedly
inside a try/catch block as shown below. (You'll have to make some other small changes too, before it will compile.) The "risky" part is moved into the try
portion, and the "what to do if it blows up" code is in the catch
part.
try { int result = DieRoller.rollRepeatedly(d, NUM_ROLLS); } catch (Exception e) { System.out.println("I just caught "+e); }
After getting it to compile, run it and verify that the exception was caught. Which pieces of code (if any) get executed after the code in the catch block?
rollRepeatedly
, but our broken die blew up again in the rollUntil
call below the try/catch. Let's move the three lines of code below the catch block up into the try and see what happens. In their place, leave a print statement that announces that the program is finished. (Make sure it's outside of the catch block, so that we can tell when something below the try/catch is executed.)
Exception
or any of its subclasses. However, we see that the actual exception being thrown is a NullPointerException
, so let's write a catch block just to handle errors of this type. Copy the block below and add it to your code. Try it immediately above and immediately below the existing catch block, but leave the original catch block in your program as well. Does it make a difference where this new block goes? (Make sure both are there and compiling properly before moving to the next step.)
catch (NullPointerException e) { System.out.println("Ooo! A null pointer error: "+e); }
HistoryDie
code and edit the constructor so that it creates an array, but one that's slightly too small:
history = new int[numSides-1];
Play around with an instance of the modified class — how many rolls does it take before it blows up? Why?
Tester
's main method now that you've modified HistoryDie
? Try it and see if you're right.
rollRepeatedly
when the exception arises rather than stopping the program. Leave the existing try/catch code in your program, but add a new try/catch block in rollRepeatedly
so that it's inside the loop and only watches the assignment statement in the loop body for exceptions. Have it catch errors of type ArrayIndexOutOfBoundsException
, and set up a counter variable so that it keeps a count of how many times the error has been caught. Print this total right before the return statement.
rollRepeatedly
? What happens next?
ArrayIndexOutOfBoundsException
to Tester
's main method as well? Leave the try/catch in rollRepeatedly
, but add a new (third) catch block in main. Where does the indexing exception get caught?
HistoryDie
constructor back so that it doesn't create an array at all. What do you think will happen? Check and see. Where did it get caught and why?
BasicDie
(yes, BasicDie
and not HistoryDie
) add the following code to the one-argument constructor. The throw
command in Java is much like a return
statement: it leaves the current method and takes a "value" with it — the Exception
object that's created by the call to new
.
if (numSides < 1) { throw new IllegalArgumentException("Negative # of sides ("+numSides+")"); }
Tester
's main method so that it tries to create a HistoryDie
with negative sides and run the program. What should happen when the main method runs?
rollRepeatedly
on a BasicDie. That is, find the T(n) for rollRepeatedly
, and be clear about what the problem size, n, is in this case. (Be sure to discuss how to handle the call to roll()
.)
rollRepeatedly
?
HistoryDie
or CrookedDie
instance rather than BasicDie
? Why or why not?
rollUntil
: What is the problem size, n, for this method? Find T(n) for rollUntil, then simplify it to get the appropriate O(n).
java.io.FileNotFoundException
rather than an IllegalArgumentException
. You'll get an error when you try to compile it. Why?
rollRepeatedly
so that it stopped and returned the total rolled so far if an exception arose?
countLetters
and for sort
? What are their corresponding O(n) terms?