我有一个关于数据验证和扫描器的问题。以下代码检查用户输入。除整数以外的任何内容都不允许,并且要求用户重新输入一个值。我的问题是,只有在扫描器为如果在外部循环中声明了扫描器,则程序将无限执行,这是为什么?

int UserInp;
    boolean dataType=false;
    while(dataType==false)
    {
        Scanner sc=new Scanner(System.in);
        try
        {

    System.out.print("\nEnter a number: ");
    UserInp=sc.nextInt();

    dataType=true;
        }
        catch(Exception JavaInputMismatch)
        {

            System.out.println("Option not available.Try again.");

        }

    }

最佳答案

有趣的问题!

发生的情况是扫描程序尝试将非整数转换为整数,并意识到它不能转换为整数-因此它引发InputMismatchException。但是,只有翻译成功,它才会越过 token 。

这意味着,无效字符串仍在输入缓冲区中,并且每次循环并尝试调用nextInt()时,转换都会失败。您永远不会将dataType设置为true,因此可以无限循环。

要查看实际效果,您可以在catch块中获取任意内容并将其打印出来:

catch(Exception JavaInputMismatch){
    System.out.println( sc.next() );
    System.out.println("Option not available.Try again.");
}

实际上,在输入无效之后,我们得到以下信息:
Enter a number: hello
hello
Option not available.Try again.

Enter a number:

而且我们不会无限循环。这是因为对next()的调用从输入缓冲区中获取了该值,并将扫描仪的指针移至该缓冲区中的下一个插槽,该插槽现在为空。因此,在这种情况下,nextInt()将等待输入。

哦,如果在循环中初始化,它能正常工作的原因是扫描程序将总是开始重新读取输入。扫描程序不会在实例之间共享状态,因此由于重新初始化,上次迭代的缓冲区中的“hello”不在下一个迭代的缓冲区中。

从技术上讲,它仍然在标准输入缓冲区中,但是扫描器指向该缓冲区的指针超出了无效字符串的范围,因为它将开始读取任何新的输入,而不是现有的输入。

10-02 05:51
查看更多