问题
I am having a little bit of a problem here. I am trying to figure out how to catch the IllegalArgumentException. For my program, if the user enters a negative integer, the program should catch the IllegalArgumentException and ask the user if he/she wants to try again. But when the exception is thrown, it doesn't give that option. It just terminates. I tried to use the try and catch method but it doesn't work for me. How do I catch this particular exception to continue to run instead of terminating?
public static void main(String[] args) throws IllegalArgumentException
{
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while(keepGoing.equals("y") || keepGoing.equals("Y"))
{
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
}
}
and
public class MathUtils
{
public static int factorial(int n)
{
int fac = 1;
for(int i = n; i > 0; i--)
{
fac *= i;
}
return fac;
}
}
回答1:
You need to add the try catch block inside the loop to continue the working for the loop. Once it hits the illegal argument exception catch it in catch block and ask if the user wants to continue
import java.util.Scanner;
public class Test {
public static void main(String[] args)
{
String keepGoing = "y";
populate(keepGoing);
}
static void populate( String keepGoing){
Scanner scan = new Scanner(System.in);
while(keepGoing.equalsIgnoreCase("y")){
try{
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
catch(IllegalArgumentException i){
System.out.println("Negative encouneterd. Want to Continue");
keepGoing = scan.next();
if(keepGoing.equalsIgnoreCase("Y")){
populate(keepGoing);
}
}
}
}
}
Hope this helps. Happy Learning :)
回答2:
I don't think you want your main()
method to be throwing an exception. Typically, this is the kind of thing that you'd put in try
and catch
blocks.
Honestly though, for this sort of thing an if/else would work better. (Unless you're just doing this as a toy example, to learn exceptions.)
Make another method called getNumber()
that throws the IllegalArgumentException
, that returns an int
. Then put it inside the try/catch in the main()
.
回答3:
public static void main(String[] args)
{
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while(keepGoing.equals("y") || keepGoing.equals("Y"))
{
int val = 0;
boolean flag=true;
while(flag){
try{
System.out.println("Enter an integer: ");
val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
flag = false;
} catch(IllegalArgumentException e){
System.out.println("value must be non-negative");
}
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
}
}
回答4:
I would suggest you add a test on the negative value and display your message on the spot, then use an else
block. Also, you could use String.equalsIgnoreCase() in your loop test like
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while (keepGoing.equalsIgnoreCase("y")) {
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0) {
System.out.println("value must be non-negative");
} else { // <-- skip negative value
System.out.println("Factorial (" + val + ") = "
+ MathUtils.factorial(val));
}
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
Also, an int factorial(int)
method can only the first 12 correct values. You could use a long
or a BigInteger like
public static BigInteger factorial(int n) {
BigInteger fac = BigInteger.ONE;
for (int i = n; i > 1; i--) {
fac = fac.multiply(BigInteger.valueOf(i));
}
return fac;
}
回答5:
Similar to some other answers, I would say that your main()
method should not throw an exception to display an error message to the user, because that is not the purpose of exception handling mechanisms in Java. Exception handling is designed to enable methods to signal that something happened that should not have happened, so the methods that call those methods will know that they need to deal with them. In general, exceptions are caught, not thrown, by main()
methods and other user interface methods.
I would make the method factorial()
throw the IllegalArgumentException
, rather than your main()
method in your program class. Your main()
method should use try
and catch
to handle this exception. With this design, if someone else wanted to use your MathUtils
class, they would know that your factorial()
method throws an IllegalArgumentException
(especially if you document your code with javadoc), and would write their code to handle the exception. In the current situation, if someone tries to call MathUtils.factorial(-1)
, the return value would be 1 because the for
loop inside factorial()
would not execute at all (because i
is initially set to -1, which is not greater than 0).
This is how I would revise your code:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String keepGoing = "y";
while(keepGoing.equalsIgnoreCase("y")) {
try { // This code might throw an exception
System.out.println("Enter an integer: ");
int val = scan.nextInt();
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
} catch (IllegalArgumentException | InputMismatchException e) {
/* An InputMismatchException is thrown if the input is not an integer.
See the documentation for Scanner method nextInt() for more details.
*/
System.out.println("You must enter a non-negative integer.");
System.out.println("Try again? (y/n)");
keepGoing = scan.next();
}
}
}
}
and
public class MathUtils throws IllegalArgumentException {
public static int factorial(int n) {
if (fac < 0) {
throw new IllegalArgumentException("value must be non-negative");
}
int fac = 1;
for(int i = n; i > 0; i--) {
fac *= i;
}
return fac;
}
}
来源:https://stackoverflow.com/questions/26960941/catching-illegalargumentexception