NoSuchElementException 无限循环与 pmd DD 异常

NoSuchElementException infinite loop vs. pmd DD-anomaly

提问人:nighty 提问时间:10/28/2021 最后编辑:nighty 更新时间:12/1/2021 访问量:59

问:

我对编程有点陌生,对 gradle 和 pmd-plugin 非常陌生,所以请怜悯。

如果用户输入一个数字,scanner.nextLine() 将在每次迭代中抛出一个 NoSuchElementException,从而创建一个无限循环。

public class Console {
    public int readInteger(String line) {
        Integer x = null;
        while(x == null) {
            try(Scanner scanner = new Scanner(System.in) {
                System.out.print(line);
                x = scanner.nextInt();
            } catch(InputMismatchException exc) {
                  //error message
            } catch(InvalidStateException exc) {
                  //error message
            } catch(NoSuchElementException exc) {
                 //error message
            }
        }
        return x;    
    }
}

我将感谢每一次帮助。

编辑:意识到,我的问题与 Scanner.nextLine() 方法结合使用。顺序无关紧要,我的循环仍然是一个具有相同 NoSuchElementException 的无限循环。

while-loop java.util.scanner pmd nosuchelementexception

评论

0赞 maloomeister 10/29/2021
您输入的输入是什么?

答:

0赞 Mansur Mavludov 10/28/2021 #1

只需更改

x = scanner.nextLine();

x = scanner.nextInt();

同样不,它不会进入无限循环,因为您使用了错误的方法,它根本不起作用。

评论

0赞 nighty 10/28/2021
scanner.nextLine() 是一个错误,没有复制代码,只是记住了它并将其写入问题中。已修复,但问题仍然存在
0赞 adangel 12/1/2021 #2

下面是完整的(可编译的)示例:

import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;

public class Console {
    public int readInteger(String line) {
        Integer x = null;
        while(x == null) {
            try(Scanner scanner = new Scanner(System.in)) {
                System.out.print(line);
                x = scanner.nextInt();
            } catch(InputMismatchException exc) {
                  //error message
            } catch(IllegalStateException exc) {
                  //error message
            } catch(NoSuchElementException exc) {
                 //error message
            }
        }
        return x;
    }

    public static void main(String[] args) {
        Console c = new Console();
        int age = c.readInteger("How old are you? ");
        System.out.printf("You are %d years old.%n", age);
    }
}

注意:InvalidStateException 不存在,它是 IllegalStateException。

保存此代码片段并使用 java 11+ 运行它,例如 .Console.javajava Console.java

如果您要输入例如。 它有效。如果您不输入整数,则“无限循环”开始,例如 .现在我们需要实际处理异常。在这种情况下,将被抛出。但是错误的输入没有被使用,并且仍在扫描程序中 - 因此再次尝试将再次抛出相同的异常。在用户输入新数据之前,我们必须先读取错误的令牌。我们可以使用 读取数据,但因此我们需要访问扫描程序,因此我们需要更早地打开扫描程序实例 - 并在外部 try-with-resources 中进行循环和错误处理。42very oldInputMismatchExceptionnextInt()nextLine()

如果用户关闭输入流(在 Windows 或 Linux 下),则会被抛出,因此我们也需要处理这种情况。 如果 Scanner 实例本身已关闭,则会引发。Ctlr+ZCltr+DNoSuchElementExceptionIllegalStateException

下面是一个固定的完整示例:

import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;

public class Console {
    public int readInteger(String line) {
        Integer x = null;
        try (Scanner scanner = new Scanner(System.in)) {
            while(x == null) {
                try {
                    System.out.print(line);
                    x = scanner.nextInt();
                } catch(InputMismatchException exc) {
                    String wrongInput = scanner.nextLine();
                    System.out.printf("The input '%s' is not a number. Please try again.%n", wrongInput);
                } catch(NoSuchElementException exc) {
                   // no input provided
                   System.exit(1);
                }
            }
        }
        return x;
    }

    public static void main(String[] args) {
        Console c = new Console();
        int age = c.readInteger("How old are you? ");
        System.out.printf("You are %d years old.%n", age);
    }
}