You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scanner在while循环菜单中出现NoSuchElementException问题

问题:Scanner循环输入时抛出NoSuchElementException

我给程序做了个主菜单,要求用户输入1-6的整数,通过switch执行对应操作后循环返回菜单(选择6退出除外)。但循环回到菜单时,还没等我输入就抛出NoSuchElementException。试过用input.nextLine()清除输入流、改用input.nextLine()转整数这些方法,都没解决。

我的代码

public static void displayMainMenu() {
        Scanner input = new Scanner(System.in);
        int option = 0;

        while(true) {
            System.out.println("Bike Registry");
            System.out.println("\nMain Menu");
            System.out.println("1. List All Bikes");
            System.out.println("2. Add a New Bike");
            System.out.println("3. Delete a Bike");
            System.out.println("4. Change a Bike Attribute");
            System.out.println("5. DEBUG: Dump objects (toString)");
            System.out.println("6. Exit");
            
            option = input.nextInt();
            input.nextLine(); 

            switch(option) {
                case 1:
                    displayAllBikes();
                    break;
                case 2:
                    addNewBike();
                    break;
                case 3:
                    deleteBike();
                    break;
                case 4:
                    alterBike();
                    break;
                case 5:
                    dumpBikes();
                    break;
                case 6:
                    System.out.println("Have a nice day!");
                    System.exit(0);
                    break;
                default:
                    System.out.println("This is not a valid option! Please select from the menu!");
                    break;
            }
        }
    }

报错信息

Exception in thread "main" java.util.NoSuchElementException
        at java.base/java.util.Scanner.throwFor(Scanner.java:937)
        at java.base/java.util.Scanner.next(Scanner.java:1594)
        at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
        at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
        at ca.sfu.cmpt213.Bike.BikeMethods.displayMainMenu(BikeMethods.java:21)
        at ca.sfu.cmpt213.Main.main(Main.java:7)

问题原因

核心问题不在主菜单代码里,而是你调用的addNewBike、deleteBike这类子方法中,大概率单独创建了Scanner对象并调用了close()方法。一旦关闭Scanner,它会连带关闭底层的System.in输入流,主菜单里的Scanner再尝试读取时,就会因为输入流已关闭抛出NoSuchElementException。

修复方案

  1. 全局复用一个Scanner对象:只在主菜单里创建一次Scanner,作为参数传递给所有需要输入的子方法,不要在每个子方法里单独新建Scanner。
  2. 禁止随意关闭Scanner:除非程序完全不需要输入(比如退出前),否则不要调用input.close(),尤其不要在子方法里关闭。

修改后的主菜单示例

public static void displayMainMenu() {
    Scanner input = new Scanner(System.in);
    int option = 0;

    while(true) {
        System.out.println("Bike Registry");
        System.out.println("\nMain Menu");
        System.out.println("1. List All Bikes");
        System.out.println("2. Add a New Bike");
        System.out.println("3. Delete a Bike");
        System.out.println("4. Change a Bike Attribute");
        System.out.println("5. DEBUG: Dump objects (toString)");
        System.out.println("6. Exit");
        
        // 先判断输入是否为整数,避免非整数输入导致的异常
        if (input.hasNextInt()) {
            option = input.nextInt();
            input.nextLine(); // 清除换行符
        } else {
            System.out.println("请输入有效的整数选项!");
            input.nextLine(); // 清空无效输入内容
            continue;
        }

        switch(option) {
            case 1:
                displayAllBikes();
                break;
            case 2:
                addNewBike(input); // 传递Scanner给子方法
                break;
            case 3:
                deleteBike(input);
                break;
            case 4:
                alterBike(input);
                break;
            case 5:
                dumpBikes();
                break;
            case 6:
                System.out.println("Have a nice day!");
                input.close(); // 退出前关闭Scanner
                System.exit(0);
                break;
            default:
                System.out.println("无效选项!请从菜单中选择!");
                break;
        }
    }
}

子方法示例(以addNewBike为例)

public static void addNewBike(Scanner input) {
    // 直接使用传入的Scanner,不要新建
    System.out.println("请输入自行车品牌:");
    String brand = input.nextLine();
    // 其他输入逻辑...
    // 绝对不要在这里调用input.close()
}

内容的提问来源于stack exchange,提问作者Gyro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:57:05