Catching IllegalArgumentException?

筅森魡賤 提交于 2021-02-20 04:09:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!