java - 在静态主方法中的 While 内尝试/捕获

标签 java exception while-loop try-catch inputmismatchexception

我不明白这其中的逻辑。如果我运行这段代码并输入一个非 int,例如字母 f,我就会陷入输出两个 println 的无限循环中,并且我没有机会再次向扫描仪输入 int...它只是不断吐出向控制台输出的内容。

public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);//<<<<<SCANNER HERE
    int opponents = 0;
    boolean opponentsCreated = false;
    while(opponentsCreated == false)
    {
        try
        {
            System.out.print("How many players: ");
            int tempOpponents = scan.nextInt();
            if(tempOpponents > 0)
            {
                opponents = tempOpponents;
                opponentsCreated = true;
            }   
        }
        catch(InputMismatchException notAValidInt)
        {
            System.out.println("Not valid - must be a number greater than 0 ");
        }   
    }
}

但是,如果我只是更改在 while 循环内声明的 Scanner,程序就会突然按预期工作:

public static void main(String[] args) {

    int opponents = 0;
    boolean opponentsCreated = false;
    while(opponentsCreated == false)
    {
        Scanner scan = new Scanner(System.in);//<<<<<SCANNER HERE
        try
        {
            System.out.print("How many players: ");
            int tempOpponents = scan.nextInt();
            if(tempOpponents > 0)
            {
                opponents = tempOpponents;
                opponentsCreated = true;
            }   
        }
        catch(InputMismatchException notAValidInt)
        {
            System.out.println("Not valid - must be a number greater than 0 ");
        }   
    }
}

老实说,我只是坐在这里两个小时,试图弄清楚我的程序到底出了什么问题,结果发现这是我在哪里声明我的扫描仪的问题,即使在两个版本的代码中扫描仪都没有出来的范围。所以现在我真的很好奇为什么它会这样工作

最佳答案

添加@HovercraftFullOfEels 答案:

根本原因是,出现上述异常时,扫描仪位置没有移动。因此扫描仪会一次又一次地响应相同的错误输入。引用JavaDoc

If the translation is successful, the scanner advances past the input that matched.

catch(InputMismatchException notAValidInt)
{
    scan.reset();
    System.out.println("Not valid - must be a number greater than 0 "); 
    //position is still 0
    scan.next(); //position is now 1
}

可视化:

Input:                  f______________
Scanner position:       ^______________

InputMismatchException  ^______________
scan.next()             _^_____________ 

相关来源(查看来源评论):

try {
            String s = next(integerPattern());
            if (matcher.group(SIMPLE_GROUP_INDEX) == null)
                s = processIntegerToken(s);
            return Integer.parseInt(s, radix);
        } catch (NumberFormatException nfe) {
            position = matcher.start(); // don't skip bad token   
            throw new InputMismatchException(nfe.getMessage());
        }

关于java - 在静态主方法中的 While 内尝试/捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18755199/

相关文章:

java - IE11 上的 Selenium 自动化(企业模式)

java - 在 Java 中使用 addAll 超过 Set 的 ConcurrentModification 异常

c++ - while循环在C++中不循环

c++ - 概念同时执行循环

java - 位移位操作不返回预期结果

java - 如果接收到无效的 JSON,则不会调用 ExceptionMapper

java - 异常在线程 "main"java.lang.UnsatisfiedLinkError : RunnerClass. parsecmdline(ILjava/lang/String;)V

javascript - HTMLCanvas 'getContext' 不是受支持的属性或方法

java - 字符串数组的索引

java - Spring:java.lang.IllegalStateException:已为此响应调用 getOutputStream()