Throwing Exceptions
File Factorials.java contains a program that
calls the factorial method of the MathUtils
class to compute the factorials of integers entered by the user. Save
these files to your directory and study the code in both,
then compile and run Factorials to see how it
works. Try several positive integers, then try a negative
number. You should find that it works for small positive integers (values < 17), but that it returns a large negative value for larger integers and that
it always returns 1 for negative integers.
-
Returning 1 as the factorial of any negative integer
is not correct -- mathematically, the factorial function is not
defined for negative
integers. To correct this, you could modify your factorial method
to check if the argument is negative, but then what? The method must return
a value, and even if it prints an error message, whatever value is returned
could be misconstrued. Instead, it should throw an exception,
indicating that something went wrong so it could not complete its
calculation. You could define your own exception class, but
there is already an exception appropriate for this situation --
IllegalArgumentException, which extends RuntimeException.
Modify your program as follows:
- Modify the header of the factorial method to indicate that
factorial can throw an IllegalArgumentException.
- Modify the body of factorial to check the value of the
argument and, if it is negative, throw an IllegalArgumentException.
Note that what you pass to throw is actually an instance
of the IllegalArgumentException class, and that the constructor
takes a String parameter. Use this parameter to be specific about what
the problem is.
- Compile and run your Factorials program after making these changes.
Now when you enter a negative number, an exception will be thrown,
terminating the program. The program ends because the exception is
not caught, so it is thrown by the main method, causing a runtime error.
- Modify the main method in your Factorials class to catch and print
the exception thrown by factorial, but then continue with the loop.
Think carefully about where you will need to put the try and
catch.
- Returning a negative number for values over 16 also is not correct.
The problem is arithmetic overflow -- the factorial is bigger than can
be represented by an int. This can also be thought of as an
IllegalArgumentException -- this factorial method is only defined
for arguments up to 16. Modify your code in factorial to check
for an argument over 16 as well as for a negative argument. You should
throw an IllegalArgumentException in either case, but pass different
messages to the constructor so that the problem is clear.