扫描仪无法读取我的输入

时间:2016-12-29 13:57:11

标签: java java.util.scanner nosuchelementexception

当我运行以下代码时:

班级Startup(由main()调用):

import java.util.ArrayList;

public class Startup {

    public void start() {

        // Build rooms
        final int WIDTH = 2;
        final int HEIGHT = 2;
        Room[][] room = new Room[WIDTH][HEIGHT];
        Rooms.build(room, WIDTH, HEIGHT);
        int x = 0;
        int y = 0;

        // Print starting room description
        Rooms.print(room, x, y);

        // Start game loop
        boolean playing = true;
        while (playing) {

            // Get user input
            String input = Input.getInput();
            System.out.println(input);

            // Movement commands
            if (input.equals("n")) {
                if (y > 0) {
                    y--;
                    Rooms.print(room, x, y);
                } else {
                    System.out.println("You can't go that way.");
                }
            }
        }
    }
}

班级Input

import java.util.Scanner;

public class Input {

    public static String getInput() {

        System.out.print("> ");
        try(Scanner in = new Scanner(System.in)) {
            String input = in.nextLine();
            input.toLowerCase();
            return input;
        }
    }
}

我将永远得到这个NoSuchElementException

java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Scanner.java:1540)
    at Input.getInput(Input.java:11)
    at Startup.start(Startup.java:36)
    at Driver.main(Driver.java:11)

如果start()中的移动命令部分被删除,一切正常。但是当包含该部分时,总是会调用该异常,这使我认为它存在错误。但我的问题是:出了什么问题?

1 个答案:

答案 0 :(得分:6)

每次拨打getInput时,您都在创建新的扫描仪。不幸的是,你每次都要关闭它:

    try(Scanner in = new Scanner(System.in)) {
        String input = in.nextLine();
        input.toLowerCase();
        return input;
    }

此构造被称为"尝试使用资源"。它会创建Scanner,这是Closeable对象,在try块的末尾,关闭

这意味着扫描仪后面的输入流也已关闭。

关闭流后,无法重新打开。来自该流的每个输入请求都将返回文件的结尾"条件。因此,每次在第一个扫描仪之后打开一个新扫描仪时,在同一个(关闭)System.in上,您将获得一个位于文件末端的空扫描仪"。

您需要做的只是打开扫描仪一次。然后对于程序的其余部分,从同一个打开的扫描仪读取。要做到这一点,你要么必须在try-with-resources中包含所有程序,要么根本不使用try-with-resources。