NoSuchElementException 无限循环与 pmd DD 异常

问题描述 投票:0回答:2

我对编程有点陌生,对 gradle 和 pmd 插件也很陌生,所以请怜悯。

如果用户输入数字,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。

java while-loop java.util.scanner pmd nosuchelementexception
2个回答
0
投票

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

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。

将此代码片段保存在

Console.java
中并使用 java 11+ 运行它,如
java Console.java

如果您要输入例如。

42
它有效。如果您不输入整数,例如,“无限循环”就会开始
very old
。现在我们需要实际处理异常。在这种情况下,将会抛出
InputMismatchException
。但是错误的输入不会被消耗,并且仍然在扫描仪中 - 因此使用
nextInt()
再次尝试将再次抛出相同的异常。在用户输入新数据之前,我们必须先读取错误的标记。我们可以使用
nextLine()
读取数据,但因此我们需要访问扫描仪,因此我们需要提前打开扫描仪实例 - 并在外部 try-with-resources 内进行循环和错误处理。

如果用户关闭输入流(在 Windows 下使用

Ctlr+Z
或在 Linux 下使用
Cltr+D
),则将抛出
NoSuchElementException
,因此我们也需要处理这种情况。如果 Scanner 实例本身关闭,则会抛出
IllegalStateException

这是一个固定的完整示例:

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

0
投票

只需更改

x = scanner.nextLine();

x = scanner.nextInt();

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

© www.soinside.com 2019 - 2024. All rights reserved.