java 捕获 IllegalArgumentException?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26960941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 10:57:13  来源:igfitidea点击:

Catching IllegalArgumentException?

javaexceptionexception-handlingtry-catchfactorial

提问by evarias

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?

我在这里遇到了一点问题。我想弄清楚如何捕获 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();
    }
}

}

}

and

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

回答by Vatsal

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

您需要在循环内添加 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);
        }
    }
    }
}
}

Hope this helps. Happy Learning :)

希望这可以帮助。快乐学习:)

回答by Adam Smith

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 tryand catchblocks.

我认为您不希望您的main()方法抛出异常。通常,这是您放入trycatch阻止的那种东西。

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.)

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

Make another method called getNumber()that throws the IllegalArgumentException, that returns an int. Then put it inside the try/catch in the main().

调用另一个getNumber()抛出 的方法IllegalArgumentException,该方法返回一个int。然后将其放入 .try/catch 文件中main()

回答by Elliott Frisch

I would suggest you add a test on the negative value and display your message on the spot, then use an elseblock. Also, you could use String.equalsIgnoreCase()in your loop test like

我建议您在负值上添加测试并当场显示您的消息,然后使用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();
}

Also, an int factorial(int)method can only the first 12 correct values. You could use a longor a BigIntegerlike

此外,一个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;
}

回答by kriyeta

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

}

}

回答by user7214865

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.

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

I would make the method factorial()throw the IllegalArgumentException, rather than your main()method in your program class. Your main()method should use tryand catchto handle this exception. With this design, if someone else wanted to use your MathUtilsclass, 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 forloop inside factorial()would not execute at all (because iis initially set to -1, which is not greater than 0).

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