为什么这段代码变成了无限循环?

时间:2013-05-01 00:00:19

标签: java while-loop infinite-loop

我写了这个简单的代码来获取一个double并且只是一直询问,直到给出一个,但是当你给一个字符串它只是变成一个无限循环而我无法弄清楚为什么。它出现这种情况的原因是什么?

Scanner scanner = new Scanner(System.in);   
double x = 0.0d;

while (true) {
    try {
        System.out.println("Gimme a double:");

        x = scanner.nextDouble();
        break;
    } catch (InputMismatchException e) {}           
}

System.out.println(x);

3 个答案:

答案 0 :(得分:7)

如果最初输入了无效的double值,它将变为无限循环。然后,Control进入异常块。由于Scanner#nextDouble不使用换行符,因此这些值会重复传递到语句

x = scanner.nextDouble();

不会阻止已经收到输入。这会导致无限循环。

不应使用空的异常块,而应使用Scanner#nextLine来使用换行符。

} catch (InputMismatchException e) {
    System.out.println("Error found: " + scanner.nextLine() + " continuing...");
}

这样Scanner#nextDouble行将在下一次迭代中阻止IO

答案 1 :(得分:2)

根据Scanner#nextDouble的javadocs,如果转换为double不成功,则不会使用字符(但如果转换成功,则不会消耗):

  

将输入的下一个标记扫描为double。这个方法会抛出   InputMismatchException如果下一个标记无法转换为   有效的双倍价值。如果翻译成功,则扫描仪   超越匹配的输入。

程序的示例输出:

$ java Main
Gimme a double:
3.5
3.5
$ java Main
Gimme a double:
blah
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
(Infinite loop here)

您必须自己使用这些字符,最好是在异常处理程序中:

} catch (InputMismatchException e) {
    System.out.println("Not a double: " + scanner.nextLine());
}

已更改程序的示例输出:

$ java Main
Gimme a double:
blah
Skipped Past: blah
Gimme a double:
3.56
3.56

答案 2 :(得分:1)

Reimeus正确地说明了无限循环发生的原因。您可以通过调用catch块中的scanner.nextLine()来修复它:

public static void main(String[] args) throws IllegalArgumentException,
        IllegalAccessException {
    /*
     * StackTest t = new StackTest();
     * 
     * for(Field f :t.getClass().getDeclaredFields()){
     * System.out.println(f.get(t)); }
     */

    Scanner scanner = new Scanner(System.in);
    double x = 0.0d;

    while (true) {
        try {
            System.out.println("Gimme a double:");

            x = scanner.nextDouble();
            break;
        } catch (InputMismatchException e) {
            scanner.nextLine();
        }
    }

    System.out.println(x);
}