使用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。
修复方案
- 全局复用一个Scanner对象:只在主菜单里创建一次Scanner,作为参数传递给所有需要输入的子方法,不要在每个子方法里单独新建Scanner。
- 禁止随意关闭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
相关产品推荐
相关产品推荐

