捕获IllegalArgumentException?

时间:2014-11-16 19:12:28

标签: java exception exception-handling try-catch factorial

我在这里遇到一些问题。我试图弄清楚如何捕获IllegalArgumentException。对于我的程序,如果用户输入一个负整数,程序应该捕获IllegalArgumentException并询问用户他/她是否想再试一次。但是当抛出异常时,它并没有提供该选项。它终止了。我尝试使用try和catch方法,但它对我不起作用。如何捕获此特定异常以继续运行而不是终止?

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();
    }
}

}

public class MathUtils
{
    public static int factorial(int n)
    {
        int fac = 1;
        for(int i = n; i > 0; i--)
        {
            fac *= i;
        }
        return fac;
    }
}

5 个答案:

答案 0 :(得分:1)

您需要在循环内添加try catch块以继续循环工作。一旦它遇到非法参数异常,就在catch块中捕获它并询问用户是否想要继续

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);
        }
    }
    }
}
}

希望这会有所帮助。 快乐学习:)

答案 1 :(得分:1)

我认为你不希望你的main()方法抛出异常。通常,这是您在trycatch块中添加的内容。

老实说,对于这种事情,if / else会更好。 (除非您只是将其作为玩具示例,否则要学习例外情况。)

制作另一个名为getNumber()的方法,该方法会抛出IllegalArgumentException,返回int。然后将其放在main()中的try / catch中。

答案 2 :(得分:0)

我建议您在负值上添加测试并在现场显示您的消息,然后使用else块。此外,您可以在循环测试中使用String.equalsIgnoreCase(),如

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();
}

此外,int factorial(int)方法只能是前12个正确的值。您可以使用longBigInteger之类的

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;
}

答案 3 :(得分:0)

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 :(得分:0)

类似于其他答案,我想说您的main()方法不应抛出异常以向用户显示错误消息,因为这不是Java中异常处理机制的目的。异常处理旨在使方法能够发信号通知某些本不应该发生的事情,因此调用这些方法的方法将知道需要对其进行处理。通常,main()方法和其他用户界面方法捕获而不抛出异常。

我会让方法factorial()抛出IllegalArgumentException,而不是程序类中的main()方法。您的main()方法应使用trycatch来处理此异常。通过这种设计,如果其他人想使用您的MathUtils类,他们会知道您的factorial()方法会抛出一个IllegalArgumentException(尤其是如果您使用javadoc编写代码),并且会编写他们的代码来处理异常。在当前情况下,如果有人尝试调用MathUtils.factorial(-1),则返回值将为1,因为for内部的factorial()循环根本不会执行(因为i最初是设置为-1,不大于0。

这就是我修改您的代码的方式:

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();
            }
        }
    }
}

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;
    }
}