Exception Handling Lab

Solve Programming Project #2 from the back of Chapter 9 of Savitch's Absolute Java:

Here is a snippet of code that inputs two integers and divides them:

Scanner scan = new Scanner( System.in); 
int n1, n2; 
double r; 
n1 = scan.nextInt(); 
n2 = scan.nextInt(); 
r = ( double) n1 / n2; 

Place this code into a try-catch block with multiple catches so that different error messages are printed if we attempt to divide by zero or if the user enters textual data instead of integers (java. util. InputMismatchException). If either of these conditions occurs, then the program should loop back and let the user enter new data.

To solve this, create a class called ExceptThis containing just a main() method. Place the above code in main(). Eclipse should complain about the Scanner line. Hold the cursor over the little red X icon and you'll see "Scanner cannot be resolved".

1. Why is this error generated?

You'll notice that Eclipse has a little lightbulb icon in the same place as the red X. This means Eclipse is offering you at least one way to fix the problem. (Keep in mind Eclipse is not all that smart. Several of its "solutions", maybe all of them, will be bogus. When using this "autofix" feature, you must carefully choose which, if any, of the proferred solutions to use.) Left click on the lightbulb and you'll see something like:

Eclipse suggests a couple of fixes

You've probably already guessed that you want to use the "Import" option. Click on it and Eclipse takes care of the rest.

Add a print statement before the nextInt() calls so we have a visible prompt for the user to enter the two numbers.

2. Run the program.

On to the guts of the problem: we're going to wrap the code with a try clause and two catch clauses. To start, add a try clause with a single catch clause for InputMismatchException. (By the way, the nextInt() call is what can throw a InputMismatchException.) When you add the catch clause for InputMismatchException you'll get a similar error message from Eclipse that we solved at the beginning of this exercise. Again, you can left click on the lightbulb to get an appropriate solution--i.e. another import.

In the catch clause print an appropriate error message.

3. Run the program, entering "whee" instead of a number for one of the two inputs. You progra should generate the error message.

Now add the second catch statement, this one to handle division by zero. Consider what data type to use for the catch's parameter. Consider also in what order the catches should appear in your code. Put into the try block a throw statement along with an appropriate if statment to identify and handle a division by zero. Consider what type of exception object you want to create with your throw.

4. Run the program, again entering "whee" instead of a number for one of the two inputs. Is the error message correct? Run the program again, entering 0 for the second argument. Is the error message correct?

Last, we have to wrap the whole try-catch stuff inside a loop. We want to loop until the user enters two numbers, so the loop will be for an indeterminate number of iterations. Thus we should use a while loop or a do-while loop. Use a new boolean variable, hasEnteredTwoNumbers to control the loop. You'll need to set hasEnteredTwoNumbers in the try clause if the user successfully entered two values. Consider carefully where the statement hasEnteredTwoNumbers = true should go.

Add a print statement at the end of main that prints the value of r. If Eclipse gives you a "r cannot be resolved to a variable", it probably means that your declaration of r is inside the try clause, but your print statement is outside the try. Move your declaration so that it precedes the try clause and is thus visible to all code within main.

5. Run your program. Does it properly keep asking for two numbers until you provide them?Try to test all possible cases: not a number, zero denominator, etc.

WARNING: What to do if your code seems to enter in an infinite loop. If you enter bad input (thus causing an InputMismatchException) the pointer into the input stream remains where it is, trapped at the "non-number" value that you entered. To deal with this, use scan.readLine() to scan through and discard the bogus input (do this in your catch clause) Now when you next try to use nextInt() you'll actually try to get brand new input from the console.

6. Add to your lab document a console transcript that demonstrates that your program handles all these cases correctly until the user enters two legal numbers.

7. Create a new class called ExceptThis2. Copy the contents of ExceptThis into ExceptThis2. You'll need to change the name of the class to be "ExceptThis2".

Modify your program, ExceptThis2.java, so that the

Scanner scan = new Scanner( System.in); 
int n1, n2; 
double r; 
n1 = scan.nextInt(); 
n2 = scan.nextInt(); 
r = ( double) n1 / n2; 

is moved to be in a new static method returnRatio. The method should return the value of r. The throw statement should now be in returnRatio, but the try and catch statements should remain in main. Make sure that returnRatio is returning a value and that it does not contain any try or catches.

7. Run your program, again testing that it will loop until the user enters two numbers and that the result of the division is output. Add to your Word document a console transcript that demonstrates that your program handles all these cases correctly until the user enters two legal numbers. Label this transcript "using returnRatio".

Zip your Word document with your java code (ExceptThis.java and ExceptThis2.java) and submit the zip file to the drop box.

 

Depending on the version of Eclipse you are working with, Eclipse might generate mysterious warning messages about "serialization". If so, see this page for how you can deal with them.