java.util.NoSuchElementException:未从 Java 扫描程序中找到行

java.util.NoSuchElementException: no Line found from the Java Scanner

提问人:Sharky 提问时间:7/20/2023 最后编辑:Mark RotteveelSharky 更新时间:7/20/2023 访问量:57

问:

我正在创建一个问答游戏,它有一个 Player 实例,用户可以创建一次,然后在 Java 中编辑用户名。我的问题出在我使用扫描仪(我很确定)上,由于某种原因,它找不到要读取的新行。我的代码给了我以下错误:

Exception in thread "main" java.util.NoSuchElementException: No line found
        at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
        at Player.setUsername(Player.java:33)
        at Quiz.printPlayerEditor(Quiz.java:118)
        at Run.main(Run.java:20)

这是 Player 中的 setUsername 方法.java它给出了错误,然后在 Quiz.java 的另一个方法 printPlayerEditor 中使用,然后在主 (Run.java) 中使用该方法:

public void setUsername(Scanner in) {
    String user = "";

    do {
        while (!in.hasNextLine() && !user.isEmpty() && user.length() < 16 ) {
            Quiz.printError();
            in.next();
        }
        user = in.nextLine(); //Line 33
        username = user;
        Quiz.setProperties("playerusername", username);

    }while(!username.equals(user));
}

给出错误的 Quiz.java 代码(使用前面的方法)

public void printPlayerEditor(Scanner in) {
    System.out.println("<><><><><><><><><><><><><><><><><><><><><><><>");
    System.out.println("Welcome to the Player editor:");
    System.out.println("Your current username is | " + player.getUsername() + " |");
    System.out.println("Please enter a new username between 1-16 characters:");
    System.out.println("<><><><><><><><><><><><><><><><><><><><><><><>");

    player.setUsername(in);

    System.out.println("Your username is now | " + player.getUsername() + " |\n");
}

最后,这在处理输入的开关盒中主要使用。这就是扫描仪的来源:

import java.util.Scanner;

public class Run {
    public static void main(String[] args) {        
        Quiz quiz = new Quiz();
        Player player = new Player();

        quiz.setPlayer(player);
        quiz.populateQuestions();
        int input = quiz.printMenu1();

        Scanner in = new Scanner(System.in);

        switch (input) {                
            case 1:
                if (Quiz.getProperties("playerusername").isEmpty()) {
                    quiz.printPlayerCreator(in);
                    input = 2;
                } else {
                    quiz.printPlayerEditor(in);
                    input = 2;
                }
                
            case 2: 
                try {
                    quiz.printUnitMenu(in);

                } catch (NullPointerException e) {
                    quiz.printPlayerCreator(in);
                
                }
                break;

            default:
                Quiz.printError();
                quiz.printMenu1();
                break;
        }

        in.close();
        
    }
}

我试过将相同的扫描程序传递到所有这些中,并且我试过使类静态化等等,但我对 Java 仍然很陌生,无法弄清楚为什么会发生这个错误。

java.util.scanner nosuchelementexception

评论

2赞 Jens 7/20/2023
不要捕获 NullPointerException。添加 null 检查
1赞 Mark Rotteveel 7/20/2023
您如何运行您的应用程序?听起来您的应用程序没有有效的 System.in(即它已关闭),这在从 IDE 运行时有时会发生。
0赞 Sharky 7/21/2023
似乎问题是扫描仪在quiz.printMenu1中关闭,我在阅读时永远不会发现这一点,因为我花了几个小时试图修复此代码,所以非常感谢!

答:

0赞 rzwitserloot 7/20/2023 #1

永远不要关闭你不负责的资源。你不负责(事实上,除非你真的知道这意味着什么,并且确定你想这样做),而“包装器”资源(例如,通常用 ),如果你关闭它们,关闭你包装的东西。换句话说 - 不要。System.inScannernew ResourceThing(refToSomeOtherResource)

一些 linting 工具会告诉您应该关闭资源。那些棉绒工具是不正确的。(在某种程度上可以理解,通过它们包装的资源来跟踪过滤器有点复杂)。

评论

0赞 Sharky 7/21/2023
感谢您的回答,我忘记删除导致问题的 close()。请问为什么棉绒工具称其为“资源泄漏”?
0赞 rzwitserloot 7/21/2023
因为它错误地认为它代表了一种资源(它没有,但有一些不正确但有些有用的理由将它们视为资源),并注意到您创建了它并且没有关闭它。Scanner
0赞 Reilas 7/20/2023 #2

"...我的问题出在我使用扫描仪(我很确定)上,由于某种原因,它找不到要读取的新行。..."

是的,hasNextLine 方法不是你要找的。

只需在 nextLine 上循环,并检查它是否符合要求。

public void setUsername(Scanner in) {
    String user;
    boolean exit = false;
    do {
        user = in.nextLine();
        if (!user.isEmpty() && user.length() < 16) exit = true;
        else Quiz.printError();
    } while (!exit);
    username = user;
    Quiz.setProperties("playerusername", username);
}

评论

0赞 Sharky 7/21/2023
嘿,刚刚尝试了您的建议,但在使用 in.nextLine() 时它仍然给出相同的错误。我尝试了几种进行验证的方法,但似乎没有一种方法能真正改变结果,在该行上给出了相同的异常。
0赞 Reilas 7/21/2023
@Sharky,您是否正在关闭任何其他使用该 System.in扫描仪